addition of hetsview component

This commit is contained in:
josch 2011-02-15 08:09:52 +01:00
parent 511507f82d
commit a1a8882d14
16 changed files with 2609 additions and 0 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
build/ build/
src/de/unibremen/informatik/hets/grammar/HetCASLGrammar.jj src/de/unibremen/informatik/hets/grammar/HetCASLGrammar.jj
src/de/unibremen/informatik/hets/grammar/*.java src/de/unibremen/informatik/hets/grammar/*.java
src/de/unibremen/informatik/hets/graphviz/dotparser/*.java
.*.swp .*.swp

View file

@ -98,6 +98,7 @@
<fileset dir="." includes="*.xml"> <fileset dir="." includes="*.xml">
<exclude name="build.xml"/> <exclude name="build.xml"/>
</fileset> </fileset>
<fileset dir="./resources"/>
</copy> </copy>
<!-- the manifest doesn't belong here but this is good for IDE's --> <!-- the manifest doesn't belong here but this is good for IDE's -->
<mkdir dir="${classes}/META-INF"/> <mkdir dir="${classes}/META-INF"/>
@ -118,6 +119,10 @@
outputdirectory="./src/de/unibremen/informatik/hets/grammar/" outputdirectory="./src/de/unibremen/informatik/hets/grammar/"
javacchome="/usr/share/java/" javacchome="/usr/share/java/"
/> />
<javacc target="./src/de/unibremen/informatik/hets/graphviz/dotparser/DotParser.jj"
outputdirectory="./src/de/unibremen/informatik/hets/graphviz/dotparser/"
javacchome="/usr/share/java/"
/>
</target> </target>
<target name = "compile" depends = "buildlibs, checkProtegeLibsAndReport, javacc"> <target name = "compile" depends = "buildlibs, checkProtegeLibsAndReport, javacc">

View file

@ -58,4 +58,21 @@
<label value="Hets"/> <label value="Hets"/>
<class value="de.unibremen.informatik.hets.protege.HetsPreferencesPane"/> <class value="de.unibremen.informatik.hets.protege.HetsPreferencesPane"/>
</extension> </extension>
<extension id="HetsVizTab"
point="org.protege.editor.core.application.WorkspaceTab">
<label value="HetsViz"/>
<class value="org.protege.editor.owl.ui.OWLWorkspaceViewsTab"/>
<editorKitId value="OWLEditorKit"/>
<index value="KKK"/>
<defaultViewConfigFileName value="viewconfig-hetsviz.xml"/>
</extension>
<extension id="HetsVizView"
point="org.protege.editor.core.application.ViewComponent">
<label value="HetsViz"/>
<class value="de.unibremen.informatik.hets.protege.HetsVizView"/>
<headerColor value="@org.protege.classcolor"/>
<category value="@org.protege.classcategory"/>
</extension>
</plugin> </plugin>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout>
<VSNode splits="0.3 0.7">
<CNode>
<Component label="Asserted hierarchy">
<Property id="pluginId" value="org.protege.editor.owl.OWLAssertedClassHierarchy"/>
</Component>
</CNode>
<CNode>
<Component label="HetsViz">
<Property id="pluginId" value="de.unibremen.informatik.hets.protege.HetsVizView"/>
</Component>
</CNode>
</VSNode>
</layout>

View file

@ -0,0 +1,194 @@
package de.unibremen.informatik.hets.graphviz;
/*
import org.apache.log4j.Logger;
import uk.ac.man.cs.mig.util.graph.graph.Graph;
import uk.ac.man.cs.mig.util.graph.layout.GraphLayoutEngine;
import uk.ac.man.cs.mig.util.graph.layout.dotlayoutengine.dotparser.DotParameterSetter;
import uk.ac.man.cs.mig.util.graph.layout.dotlayoutengine.dotparser.DotParser;
import uk.ac.man.cs.mig.util.graph.layout.dotlayoutengine.dotparser.ParseException;
import uk.ac.man.cs.mig.util.graph.outputrenderer.GraphOutputRenderer;
import uk.ac.man.cs.mig.util.graph.outputrenderer.impl.DotOutputGraphRenderer;
import uk.ac.man.cs.mig.util.graph.renderer.impl.DefaultEdgeLabelRenderer;
import uk.ac.man.cs.mig.util.graph.renderer.impl.DefaultNodeLabelRenderer;
*/
import de.unibremen.informatik.hets.graphviz.dotparser.DotParser;
import java.io.*;
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: Jan 16, 2004<br><br>
*
* matthew.horridge@cs.man.ac.uk<br>
* www.cs.man.ac.uk/~horridgm<br><br>
*
*/
public class DotGraphLayoutEngine
{
//private static Logger log = Logger.getLogger(DotGraphLayoutEngine.class);
//private GraphOutputRenderer renderer;
public static final int LAYOUT_LEFT_TO_RIGHT = 0;
public static final int LAYOUT_TOP_TO_BOTTOM = 1;
private int layoutDirection = LAYOUT_LEFT_TO_RIGHT;
public DotGraphLayoutEngine()
{
//renderer = new DotOutputGraphRenderer(new DefaultNodeLabelRenderer(), new DefaultEdgeLabelRenderer());
}
/*
public void setGraphOutputRenderer(GraphOutputRenderer renderer)
{
this.renderer = renderer;
}
*/
/**
* Lays out the specified <code>Graph</code>
* @param g The <code>Graph</code>
*/
public synchronized Graph layoutGraph(File file)
{
long t0, t1, t2;
Graph g = new Graph();
Node n0 = new Node("0");
Node n1 = new Node("1");
Node n2 = new Node("2");
Node n3 = new Node("3");
Node n4 = new Node("4");
Node n5 = new Node("5");
g.add(n0);
g.add(n1);
g.add(n2);
g.add(n3);
g.add(n4);
g.add(n5);
Edge e0 = new Edge(n0, n1, "0", 1);
Edge e1 = new Edge(n0, n2, "1", 1);
Edge e2 = new Edge(n0, n3, "2", 1);
Edge e3 = new Edge(n0, n4, "3", 1);
Edge e4 = new Edge(n3, n0, "4", 1);
Edge e5 = new Edge(n4, n5, "5", 1);
g.add(e0);
g.add(e1);
g.add(e2);
g.add(e3);
g.add(e4);
g.add(e5);
DotProcess process = new DotProcess();
// Render the graph in DOT and send it to the
// DOT Process the be laid out
/*
if(layoutDirection == LAYOUT_LEFT_TO_RIGHT)
{
renderer.setRendererOption(DotOutputGraphRenderer.LAYOUT_DIRECTION, "LR");
}
else
{
renderer.setRendererOption(DotOutputGraphRenderer.LAYOUT_DIRECTION, "TB");
}
*/
//DotLayoutEngineProperties properties = DotLayoutEngineProperties.getInstance();
/*
renderer.setRendererOption(DotOutputGraphRenderer.RANK_SPACING, Double.toString(properties.getRankSpacing()));
renderer.setRendererOption(DotOutputGraphRenderer.SIBLING_SPACING, Double.toString(properties.getSiblingSpacing()));
*/
try
{
//File file = File.createTempFile("OWLVizScratch", null);
//file.deleteOnExit();
//log.debug("TRACE(DotGraphLayoutEngine): TempFile: " + file.getAbsolutePath());
//FileOutputStream fos = new FileOutputStream(file);
//renderer.renderGraph(g, fos);
//fos.close();
if(process.startProcess(file.getAbsolutePath()) == false)
{
return null;
}
// Read outputrenderer from process and parse it
InputStream is = null;
is = new FileInputStream(file);
// InputStream is = process.getReader();
if(is != null)
{
try
{
DotParameterSetter paramSetter = new DotParameterSetter();
//paramSetter.setGraph(g);
paramSetter.setGraph(g);
DotParser.parse(paramSetter, is);
}
catch(ParseException e)
{
e.printStackTrace();
}
t1 = System.currentTimeMillis();
// parser.parse(is);
process.killProcess();
process = null;
}
t2 = System.currentTimeMillis();
}
catch(IOException ioEx)
{
ioEx.printStackTrace();
}
return g;
}
/**
* Sets the direction of the layout.
* @param layoutDirection The layout direction. This should be one of
* the constants <code>DotGraphLayoutEngine.LAYOUT_LEFT_TO_RIGHT</code> or
* <code>DotGraphLayoutEngine.LAYOUT_TOP_TO_BOTTOM</code>.
*/
public void setLayoutDirection(int layoutDirection)
{
this.layoutDirection = layoutDirection;
}
/**
* Gets the layout direction.
* @return The direction of the layout. <code>DotGraphLayoutEngine.LAYOUT_LEFT_TO_RIGHT</code> or
* <code>DotGraphLayoutEngine.LAYOUT_TOP_TO_BOTTOM</code>.
*/
public int getLayoutDirection()
{
return layoutDirection;
}
}

View file

@ -0,0 +1,445 @@
package de.unibremen.informatik.hets.graphviz;
/*
import uk.ac.man.cs.mig.util.graph.graph.Edge;
import uk.ac.man.cs.mig.util.graph.graph.Graph;
import uk.ac.man.cs.mig.util.graph.graph.Node;
import uk.ac.man.cs.mig.util.graph.renderer.NodeLabelRenderer;
import uk.ac.man.cs.mig.util.graph.renderer.impl.DefaultNodeLabelRenderer;
*/
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: May 7, 2004<br><br>
* <p/>
* matthew.horridge@cs.man.ac.uk<br>
* www.cs.man.ac.uk/~horridgm<br><br>
* <p/>
* <p/>
* The <code>DotParameterSetter</code> sets the various attributes
* of a <code>Graph</code> and it's <code>Node</code>s and <code>Edge</code>s,
* using attribute/value <code>String</code> pairs (that come from a dot file).
*/
public class DotParameterSetter
{
private Graph graph;
private HashMap nodeMap;
private HashMap edgeMap;
private Edge[] edges;
private Node[] nodes;
//private NodeLabelRenderer labelRen;
private static int graphHeight = 0;
public DotParameterSetter()
{
//labelRen = new NodeLabelRenderer();
}
/**
* Sets the <code>Graph</code> whose <code>Node</code>s and
* <code>Edge</code>s the attributes will apply to.
*
* @param g The <code>Graph</code>
*/
public void setGraph(Graph g)
{
// Set the graph
graph = g;
// Reset the graph height
graphHeight = 0;
// Extract the Nodes
nodes = graph.getNodes();
// Put the Nodes into the NodeMap. This allows us
// to retrive a Node based on the Node label, which
// is generated
nodeMap = new HashMap(nodes.length);
for(int i = 0; i < nodes.length; i++)
{
//nodeMap.put(labelRen.getLabel(nodes[i]), nodes[i]);
nodeMap.put(nodes[i].getUserObject().toString(), nodes[i]);
}
edges = graph.getEdges();
edgeMap = new HashMap(edges.length);
String tail;
String head;
// Put the edge keys into the edge map
for(int i = 0; i < edges.length; i++)
{
//tail = labelRen.getLabel(edges[i].getTailNode());
tail = edges[i].getTailNode().getUserObject().toString();
//head = labelRen.getLabel(edges[i].getHeadNode());
head = edges[i].getHeadNode().getUserObject().toString();
edgeMap.put(new NodeEdgeKey(tail, head), edges[i]);
}
}
/**
* Sets an attribute for the <code>Graph</code>.
*
* @param name The name of the attribute, for example,
* "bb" will set the <code>Graph</code> bounding box.
* @param value The value of the attribute, for example,
* the value "10,20,300,400" might represent a bounding
* box located at (10, 20), with a width of 300 and height
* of 400.
*/
public void setGraphAttribute(String name, String value)
{
if(name.equals("bb"))
{
Rectangle r = parseRect(value);
if(r != null)
{
graph.setShape(r);
graphHeight = r.height;
}
}
}
/**
* Sets the attribute for a specified <code>Node</code>.
*
* @param nodeID The name of the <code>Node</code>.
* @param name The name of the attribute
* @param value The value of the attribute
*/
public void setNodeAttribute(String nodeID, String name, String value)
{
if(name.equals("pos"))
{
Node n = (Node) nodeMap.get(nodeID);
if(n != null)
{
Point p = parsePoint(value);
if(p != null)
{
n.setPosition(p.x, graphHeight - p.y);
}
}
} else if (name.equals("label")) {
Node n = (Node) nodeMap.get(nodeID);
if (n != null) {
n.setLabel(value);
}
}
}
/**
* Sets the attribute for a specified <code>Edge</code>. The <code>Edge</code>
* is specified in terms of the <code>Node</code>s that it connects.
*
* @param tailNodeID The tail <code>Node</code> name.
* @param headNodeID The head <code>Node</code> name.
* @param name The name of the attribute
* @param value The value of the attribute
*/
public void setEdgeAttribute(String tailNodeID, String headNodeID, String name, String value)
{
NodeEdgeKey nek = new NodeEdgeKey(tailNodeID, headNodeID);
Edge edge = (Edge) edgeMap.get(nek);
if(edge != null)
{
if(name.equals("pos"))
{
setEdgePath(edge, value);
}
else if(name.equals("lp"))
{
Point lp = new Point();
lp = parsePoint(value);
edge.setLabelPosition(lp.x, graphHeight - lp.y);
}
}
}
/**
* Sets the positions of a path origin, and the ctrl points
* of the path.
*
* @param edge The <code>Edge</code> that will have it's
* points set.
* @param value The <code>String</code> containing the edge
* start point and ctrl points.
*/
public void setEdgePath(Edge edge, String value)
{
// Points are separated by spaced
// Points be be preceded by the letter
// s or the letter e, indicating the arrowhead point
// at the start or the arrowhead point at the end.
// Extract the edge points from the the string - a list of points separated by spaces
StringTokenizer tokenizer = new StringTokenizer(value);
String token;
// Create a list to hold the points in
ArrayList<Point> edgePoints = new ArrayList<Point>(10); // A size of around 10 should be enough
Point edgePoint;
Point startPoint = null;
Point endPoint = null;
while(tokenizer.hasMoreTokens())
{
token = tokenizer.nextToken();
if(token.charAt(0) == 's')
{
startPoint = parsePoint(token.substring(2, token.length()));
startPoint.y = graphHeight - startPoint.y;
}
else if(token.charAt(0) == 'e')
{
endPoint = parsePoint(token.substring(2, token.length()));
endPoint.y = graphHeight - endPoint.y;
}
else
{
edgePoint = parsePoint(token);
edgePoint.y = graphHeight - edgePoint.y;
edgePoints.add(edgePoint);
}
}
// Put the information into the edge
// Clear any information that is in the
// edge.
edge.resetPath();
// Set the start of the edge path
edgePoint = edgePoints.get(0);
edge.setPathOrigin(edgePoint.x, edgePoint.y);
// Set the positions of the control points.
int numberOfCtrlPoints = (edgePoints.size() - 1) / 3;
// Control points for bezier curve
Point cp1, cp2, cp3;
int ctrlPointIndex;
// Remember, the first point in the list is
// the arrowhead tip. The second point is
// the first point on the edge path.
for(int i = 0; i < numberOfCtrlPoints; i++)
{
ctrlPointIndex = i * 3 + 1;
cp1 = edgePoints.get(ctrlPointIndex);
cp2 = edgePoints.get(ctrlPointIndex + 1);
cp3 = edgePoints.get(ctrlPointIndex + 2);
edge.pathTo(cp1.x, cp1.y, cp2.x, cp2.y, cp3.x, cp3.y);
}
Point arrowheadBase;
if(startPoint != null)
{
// Arrowhead base should be first point in the list
arrowheadBase = edgePoints.get(0);
// Set the arrowhead, which goes from tip to base points
edge.setArrowTail(arrowheadBase.x, arrowheadBase.y, startPoint.x, startPoint.y);
}
if(endPoint != null)
{
// Arrowhead base should be the last point in the list
arrowheadBase = edgePoints.get(edgePoints.size() - 1);
// Set the arrowhead, which goes from tip to base points
edge.setArrowTail(arrowheadBase.x, arrowheadBase.y, endPoint.x, endPoint.y);
}
}
/**
* Parses a point in the form of "x,y".
*
* @param data The <code>String</code> containing the point (in
* format "x,y").
* @return A point that is located at (x, y)
*/
public Point parsePoint(String data)
{
Point p = null;
int commaPos = data.indexOf(",");
if(commaPos != -1)
{
int x = (int) Float.parseFloat(data.substring(0, commaPos));
int y = (int) Float.parseFloat(data.substring(commaPos + 1, data.length()));
p = new Point(x, y);
}
return p;
}
/**
* Parses a <code>String</code> that describes a <code>Rectangle</code>
*
* @param data The <code>String</code> in the format "x,y,w,h"
* @return A rectangle that is located at (x, y), has a width w and
* a height h.
*/
public Rectangle parseRect(String data)
{
Rectangle rect = null;
int start = 0;
int commaPos = 0;
commaPos = data.indexOf(',', start);
rect = new Rectangle();
rect.x = Integer.parseInt(data.substring(start, commaPos));
start = commaPos + 1;
commaPos = data.indexOf(',', start);
rect.y = Integer.parseInt(data.substring(start, commaPos));
start = commaPos + 1;
commaPos = data.indexOf(',', start);
rect.width = Integer.parseInt(data.substring(start, commaPos));
start = commaPos + 1;
rect.height = Integer.parseInt(data.substring(start, data.length()));
return rect;
}
/**
* An inner class that is used to key the names of two
* <code>Nodes</code> (tail node and head node)
* to an edge.
*/
private class NodeEdgeKey
{
private String tail;
private String head;
public NodeEdgeKey(String tail, String head)
{
this.tail = tail;
this.head = head;
}
public int hashCode()
{
int hashCode = tail.hashCode() * 37 + head.hashCode() * 17;
return hashCode;
}
public boolean equals(Object obj)
{
if(obj == this)
{
return true;
}
if(getClass() != obj.getClass())
{
return false;
}
DotParameterSetter.NodeEdgeKey nek = (DotParameterSetter.NodeEdgeKey) obj;
return nek.head.equals(this.head) && nek.tail.equals(this.tail);
}
public String toString()
{
return "NodeEdgeKey(" + tail + " -> " + head + " hashCode: " + this.hashCode() + ")";
}
}
}

View file

@ -0,0 +1,61 @@
package de.unibremen.informatik.hets.graphviz;
//import org.apache.log4j.Logger;
import java.io.*;
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: May 18, 2004<br><br>
* <p/>
* matthew.horridge@cs.man.ac.uk<br>
* www.cs.man.ac.uk/~horridgm<br><br>
*/
public class DotPreParser
{
//private static Logger logger = Logger.getLogger(DotPreParser.class);
public static String preParse(InputStream is) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
StringWriter sr = new StringWriter();
try
{
String line = br.readLine();
while(line != null)
{
if(line.endsWith("\\"))
{
// We need to concatenate the next line
while(line.endsWith("\\"))
{
sr.write(line.substring(0, line.length() - 1));
line = br.readLine();
}
}
sr.write(line);
line = br.readLine();
}
}
catch(IOException e)
{
//logger.error(e);
}
return sr.toString();
}
catch (UnsupportedEncodingException e) {
//logger.error(e);
}
return null;
}
}

View file

@ -0,0 +1,107 @@
package de.unibremen.informatik.hets.graphviz;
import java.io.IOException;
import javax.swing.JOptionPane;
//import org.apache.log4j.Logger;
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: Jan 16, 2004<br><br>
* <p/>
* matthew.horridge@cs.man.ac.uk<br>
* www.cs.man.ac.uk/~horridgm<br><br>
* <p/>
* A wrapper for a native dot process.
*/
public class DotProcess {
//private static Logger log = Logger.getLogger(DotProcess.class);
private Process process;
/**
* Contructs a <code>DotProcess</code>, and starts
* the native dot process. Using the default process
* path for the particular platfrom being used.
*/
public DotProcess() {
}
/**
* Lays out a graph using the dot application
*
* @param fileName A file that acts as a 'scratch pad'
* The graph is read from this file, and then export
* to the same file in attributed dot format.
* @return <code>true</code> if the process completed without
* any errors, or <code>false</code> if the process did not
* complete.
*/
public boolean startProcess(String fileName) {
if(process != null) {
killProcess();
}
Runtime r = Runtime.getRuntime();
//DotLayoutEngineProperties properties = DotLayoutEngineProperties.getInstance();
try {
//process = r.exec(properties.getDotProcessPath() + " " + fileName + " -q -o " + fileName);
process = r.exec("/usr/bin/dot" + " " + fileName + " -q -o " + fileName);
try {
process.waitFor();
return true;
}
catch(InterruptedException irEx) {
irEx.printStackTrace();
return false;
}
}
catch(IOException ioEx) {
String errMsg = "An error related to DOT has occurred. " + "This error was probably because OWLViz could not" + " find the DOT application. Please ensure that the" + " path to the DOT application is set properly";
String dlgErrMsg = "<html><body>A DOT error has occurred.<br>" +
"This is probably because OWLViz could not find the DOT application.<br>" +
"OWLViz requires that Graphviz (http://www.graphviz.org/) is installed<br>" +
" and the path to the DOT application is set properly (in options).</body></html>";
JOptionPane.showMessageDialog(null, dlgErrMsg, "DOT Error", JOptionPane.ERROR_MESSAGE);
// Display on stderr
//log.error("DOT Process Error:");
//log.error(ioEx.getMessage());
//log.error(errMsg);
return false;
// Display a dialog
//ioEx.printStackTrace();
}
}
/**
* Kills the native dot process (if it was started
* successfully).
*/
protected void killProcess() {
if(process != null) {
process.destroy();
process = null;
}
}
}

View file

@ -0,0 +1,305 @@
package de.unibremen.informatik.hets.graphviz;
/*
import uk.ac.man.cs.mig.util.graph.graph.Edge;
import uk.ac.man.cs.mig.util.graph.graph.Node;
import uk.ac.man.cs.mig.util.graph.model.GraphModel;
*/
import java.awt.*;
import java.awt.geom.GeneralPath;
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: Jan 14, 2004<br><br>
*
* matthew.horridge@cs.man.ac.uk<br>
* www.cs.man.ac.uk/~horridgm<br><br>
*
*/
public class Edge
{
private Object userObject;
private Node tailNode;
private Node headNode;
private Point labelPos;
private GeneralPath path;
private static final int ARROWHEAD_HALF_BASE_WIDTH = 4;
private int direction;
public Edge(Node tailNode, Node headNode, Object userObject, int direction)
{
this.tailNode = tailNode;
this.headNode = headNode;
this.userObject = userObject;
labelPos = new Point();
path = new GeneralPath();
/*
if(direction == GraphModel.DIRECTION_NONE ||
direction == GraphModel.DIRECTION_FORWARD ||
direction == GraphModel.DIRECTION_BACK ||
direction == GraphModel.DIRECTION_BOTH)
{
this.direction = direction;
}
*/
this.direction = 1;
}
/**
* Returns the node that the <i>head</i> of the head
* is connected to.
* @return The head Node.
*/
public Node getHeadNode()
{
return headNode;
}
/**
* Returns the node that the <i>tail</i> of the edge
* is connected to.
* @return The tail Node.
*/
public Node getTailNode()
{
return tailNode;
}
/**
* Allows an object to be associated with the <code>Edge</code>
* @param o The object to be set as the userObject
*/
public void setUserObject(Object o)
{
userObject = o;
}
/**
* Gets the userObject, previously set with <code>setUserObject(Object o)</code>
* @return The userObject, or <code>null</code> if no object has been set.
*/
public Object getUserObject()
{
return userObject;
}
/**
* Causes any information in the path that represents the <code>Egde</code>
* to be cleared, such as origin location and any control points.
*/
public void resetPath()
{
path.reset();
}
/**
* Sets the location of the start of the path that represents
* the <code>Edge</code>.
* @param x The horizontal location.
* @param y The vertical location.
*/
public void setPathOrigin(int x, int y)
{
path.reset();
path.moveTo(x, y);
}
/**
* Extends the <code>Edge</code> using the following control points to
* form a Bezier curve extension to the end point (x3, y3).
* @param x1 Horizontal location of control point 1
* @param y1 Vertical location of control point 1
* @param x2 Horizontal location of control point 2
* @param y2 Vertical location of control point 2
* @param x3 Horizontal location of the end point.
* @param y3 Vertical location of the end point.
*/
public void pathTo(int x1, int y1, int x2, int y2, int x3, int y3)
{
// If the path is a horizontal straighline, then add it as
// such - there appears to be a 'feature' where
// the curve will not be drawn if all y control points
// are equal.
if(y1 == y2 && y2 == y3)
{
path.lineTo(x3, y3);
}
else
{
path.curveTo(x1, y1, x2, y2, x3, y3);
}
}
/**
* Extends the <code>Edge</code> to the specified location using
* a straight line.
* @param x The horizontal location of the end point.
* @param y The vertical location of the end point.
*/
public void pathTo(int x, int y)
{
path.lineTo(x, y);
}
/**
* Retrieves the position of the <code>Edge's</code> label.
* @return A <code>Point</code> containing the position of
* the label.
*/
public Point getLabelPosition()
{
return labelPos;
}
/**
* Sets the <code>Edge</code>'s label position.
* @param x The horizontal location (in pixels).
* @param y The vertical location (in pixels).
*/
public void setLabelPosition(int x, int y)
{
labelPos.x = x;
labelPos.y = y;
}
public void setArrowHead(int baseX, int baseY, int tipX, int tipY)
{
int deltaX = tipX - baseX;
int deltaY = tipY - baseY;
double length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
double vecX = (deltaX / length) * ARROWHEAD_HALF_BASE_WIDTH;
double vecY = (deltaY / length) * ARROWHEAD_HALF_BASE_WIDTH;
int x1;
int y1;
int x2;
int y2;
x1 = (int)(baseX - vecY);
y1 = (int)(baseY + vecX);
x2 = (int)(baseX + vecY);
y2 = (int)(baseY - vecX);
path.moveTo(tipX, tipY);
path.lineTo(x1, y1);
path.lineTo(x2, y2);
path.lineTo(tipX, tipY);
}
/**
* Sets the <code>Edge's</code> arrowtail
*
* @param baseX The x location of the centre of the arrowhead baseline.
* @param baseY The y location of the centre of the arrowhead tip.
* @param tipX The x location of the tip of the arrowhead.
* @param tipY The y location of the tip of the arrowhead.
*/
public void setArrowTail(int baseX, int baseY, int tipX, int tipY)
{
int deltaX = tipX - baseX;
int deltaY = tipY - baseY;
double length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
double vecX = (deltaX / length) * ARROWHEAD_HALF_BASE_WIDTH;
double vecY = (deltaY / length) * ARROWHEAD_HALF_BASE_WIDTH;
int x1;
int y1;
int x2;
int y2;
x1 = (int)(baseX - vecY);
y1 = (int)(baseY + vecX);
x2 = (int)(baseX + vecY);
y2 = (int)(baseY - vecX);
path.moveTo(tipX, tipY);
path.lineTo(x1, y1);
path.lineTo(x2, y2);
path.lineTo(tipX, tipY);
}
/**
* Gets the <code>Shape</code> that represents the <code>Edge</code>.
* @return The <code>Shape</code> of the <code>Edge</code>.
*/
public Shape getShape()
{
return path;
}
/**
* Gets the direction of the <code>Edge</code>. This is one of the
* predefined direction from the <code>Edge</code> interface.
*
* @return The direction of the <code>Edge</code>.
*/
public int getDirection()
{
return direction;
}
public int hashCode()
{
return tailNode.hashCode() * 13 + headNode.hashCode() * 37;
}
public boolean equals(Object obj)
{
if(obj instanceof Edge)
{
if(obj == this)
{
return true;
}
else
{
Edge edge = (Edge)obj;
if(edge.getTailNode().equals(tailNode) && edge.getHeadNode().equals(headNode))
{
return true;
}
else
{
return false;
}
}
}
return false;
}
}

View file

@ -0,0 +1,213 @@
package de.unibremen.informatik.hets.graphviz;
/*
import uk.ac.man.cs.mig.util.graph.controller.Controller;
import uk.ac.man.cs.mig.util.graph.graph.Edge;
import uk.ac.man.cs.mig.util.graph.renderer.EdgeRenderer;
*/
import javax.swing.*;
import java.awt.*;
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: Jan 14, 2004<br><br>
*
* matthew.horridge@cs.man.ac.uk<br>
* www.cs.man.ac.uk/~horridgm<br><br>
*
*/
public class EdgeRenderer
{
// private Controller controller;
private static Color edgeColor;
private Color parentEdgeColor;
private Color childEdgeColor;
private Stroke selEdgeStroke;
private Stroke edgeStroke;
private static double edgeBrightness = 0.4;
private Font labelFont;
public EdgeRenderer()
{
// this.controller = controller;
updateEdgeColor();
parentEdgeColor = new Color(125, 0, 125);
childEdgeColor = new Color(0, 125, 0);
selEdgeStroke = new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
edgeStroke = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
JPanel pan = new JPanel();
Font font = pan.getFont();
labelFont = font.deriveFont(10.0f);
}
/**
* Gets the brightness of edges in the graph.
* @return The edge brightness. A brightness of 0.0
* is equivalent to black, a brightness of 1.0 is
* equivalent to white.
*/
public static double getEdgeBrightness()
{
return edgeBrightness;
}
/**
* Sets the brightness (level of gray) of edges in the graph.
* @param brightness The brightness. A brightness of 0.0 is
* equivalent to black, a brightness of 1.0 is equivalent to
* white. The brightness is clipped between 0.0 and 1.0
*/
public static void setEdgeBrightness(double brightness)
{
if(brightness < 0)
{
brightness = 0;
}
if(brightness > 1)
{
brightness = 1;
}
edgeBrightness = brightness;
updateEdgeColor();
}
protected static void updateEdgeColor()
{
int brightness = (int)(edgeBrightness * 255);
edgeColor = new Color(brightness, brightness, brightness);
}
/**
* Called to render an <code>Edge</code>. Typically, the <code>Shape</code>
* will be a <code>GeneralPath</code>.
* @param edge The <code>Edge</code> to be rendered.
* @param g2 The Graphics2D object on to which the <code>Edge</code> should be rendered.
* @param forPrinting A flag to indicate if the graphics are being drawn to produce an
* image for printing, or to draw onto the screen.
*/
public void renderEdge(Graphics2D g2, Edge edge, boolean forPrinting, boolean drawDetail)
{
Shape sh = edge.getShape();
// Only render the edge if we are within
// the clip bounds
if(sh.intersects(g2.getClipBounds()))
{
g2.setColor(getEdgeColor(edge, forPrinting));
Stroke oldStroke = g2.getStroke();
g2.setStroke(getEdgeStroke(edge, forPrinting));
g2.draw(sh);
g2.setStroke(oldStroke);
// Render label
if(drawDetail == true) {
// String label = controller.getEdgeLabelRenderer().getEdgeLabel(edge);
String label = null;
if(label != null)
{
Font oldFont = g2.getFont();
g2.setFont(labelFont);
int halfFontWidth = g2.getFontMetrics().stringWidth(label) / 2;
int fudge = g2.getFontMetrics().getHeight() / 2;
g2.drawString(label, edge.getLabelPosition().x - halfFontWidth, edge.getLabelPosition().y + fudge);
// Ellipse2D.Double el = new Ellipse2D.Double(edge.getLabelPosition().x, edge.getLabelPosition().y, 3, 3);
// g2.setColor(Color.RED);
// g2.draw(el);
g2.setFont(oldFont);
}
}
}
}
protected Color getEdgeColor(Edge edge, boolean forPrinting)
{
// Object selObj = controller.getGraphSelectionModel().getSelectedObject();
Object selObj = null;
Color color = Color.DARK_GRAY;
if(forPrinting == false && selObj != null)
{
if(selObj == edge.getHeadNode().getUserObject()) // Node equals based on IDENTITY of encapsulated
{ // object
color = childEdgeColor;
}
else if(selObj == edge.getTailNode().getUserObject())
{
color = parentEdgeColor;
}
else
{
color = edgeColor;
}
}
else
{
color = edgeColor;
}
return color;
}
protected Stroke getEdgeStroke(Edge edge, boolean forPrinting)
{
Stroke stroke = edgeStroke;
// Object selObj = controller.getGraphSelectionModel().getSelectedObject();
Object selObj = null;
if(forPrinting == false && selObj != null)
{
if(selObj == edge.getHeadNode().getUserObject()) // Node equals based on IDENTITY of encapsulated
{ // object
stroke = selEdgeStroke;
}
else if(selObj == edge.getTailNode().getUserObject())
{
stroke = selEdgeStroke;
}
else
{
stroke = edgeStroke;
}
}
else
{
stroke = edgeStroke;
}
return stroke;
}
}

View file

@ -0,0 +1,293 @@
package de.unibremen.informatik.hets.graphviz;
/*
import uk.ac.man.cs.mig.util.graph.graph.Edge;
import uk.ac.man.cs.mig.util.graph.graph.Graph;
import uk.ac.man.cs.mig.util.graph.graph.Node;
*/
import java.awt.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: Jan 14, 2004<br><br>
*
* matthew.horridge@cs.man.ac.uk<br>
* www.cs.man.ac.uk/~horridgm<br><br>
*
*/
public class Graph
{
private Map nodes;
private Map edges;
private Shape shape;
public Graph()
{
nodes = new HashMap();
edges = new HashMap();
shape = new Rectangle();
}
/**
* Adds a <code>Node</code> to the graph. If the <code>Graph</code>
* already contains the <code>Node</code> then the <code>Node</code>
* will not be added.
* @param node The node to be added.
*/
public void add(Node node)
{
if(nodes.containsKey(node) == false)
{
nodes.put(node, node);
}
}
/**
* Removes the specified <code>Node</code> from the <code>Graph</code>.
* Note that any edges that have this node as their head node, or tail node
* will also be removed.
* @param node The <code>Node</code> to be removed.
*/
public void remove(Node node)
{
if(nodes.containsKey(node))
{
// Remove the node
nodes.remove(node);
Iterator it = getEdgeIterator();
Edge edge;
// Remove any edges that are connected to the node.
while(it.hasNext())
{
edge = (Edge)it.next();
if(node.equals(edge.getTailNode()))
{
it.remove();
}
else if(node.equals(edge.getHeadNode()))
{
it.remove();
}
}
}
}
/**
* Adds an <code>Edge</code> to the graph. Note that the Edge will
* only be added if the nodes that the edge connects are contained
* in the graph.
* @param edge The <code>Edge</code> to be added.
*/
public void add(Edge edge)
{
if(nodes.containsKey(edge.getTailNode()) && nodes.containsKey(edge.getHeadNode()))
{
EdgeKey key = new EdgeKey(edge);
edges.put(key, edge);
}
}
/**
* Removes an <code>Edge</code> from the <code>Graph</code>.
* @param edge The <code>Edge</code> to be removed.
*/
public void remove(Edge edge)
{
edges.remove(new EdgeKey(edge));
}
/**
* Removes the <code>Edge</code> that connects the specified
* <code>Nodes</code> (if the <code>Nodes</code> are contained
* in the <code>Graph</code>.
* @param tailNode The <code>Egde</code>'s tail <code>Node</code>.
* @param headNode The <code>Edge</code>'s head <code>Node</code>.
*/
public void remove(Node tailNode, Node headNode)
{
edges.remove(new EdgeKey(tailNode, headNode));
}
/**
* Removes all the edges and nodes from the graph.
*/
public void removeAll()
{
edges = new HashMap();
nodes = new HashMap();
}
/**
* Returns the number of <code>Nodes</code> that the <code>Graph</code>
* contains.
* @return The number of <code>Nodes</code>.
*/
public int getNodeCount()
{
return nodes.size();
}
/**
* Returns the number of <code>Edges</code> that the <code>Graph</code>
* contains.
* @return The number of <code>Edges</code>.
*/
public int getEdgeCount()
{
return edges.size();
}
/**
* Retrieves an <code>Iterator</code> that can be
* used to traverse the <code>Nodes</code> in the <code>Graph</code>.
* @return The <code>Iterator</code>.
*/
public Iterator getNodeIterator()
{
return nodes.keySet().iterator();
}
/**
* Retrieves an <code>Iterator</code> that can be
* used to traverse the <code>Edges</code> in the <code>Graph</code>.
* @return The <code>Iterator</code>.
*/
public Iterator getEdgeIterator()
{
return edges.values().iterator();
}
/**
* Gets the shape that isShown all of the <code>Nodes</code> and
* <code>Edges</code> belonging to the <code>Graph</code>.
* @return A shape that describes the <code>Graphs</code> bounds.
*/
public Shape getShape()
{
return shape;
}
/**
* Sets the shape that describes the <code>Graph</code> bounds.
* @param shape The <code>Shape</code> bounding the graph.
*/
public void setShape(Shape shape)
{
this.shape = shape;
}
/**
* Determines if the <code>Graph</code> isShown the specified <code>Node</code>.
* @param node The <code>Node</code>
* @return <code>true</code> if the <code>Graph</code> isShown the <code>Node</code>
* or <code>false</code> if the <code>Graph</code> does not contain the <code>Node</code>.
*/
public boolean contains(Node node)
{
return nodes.containsKey(node);
}
/**
* Determines if the <code>Graph</code> isShown the specified <code>Edge</code>.
* @param edge The <code>Edge</code>.
* @return <code>true</code> if the <code>Graph</code> isShown the <code>Edge</code>
* or <code>false</code> if the <code>Graph</code> does not contain the <code>Edge</code>.
*/
public boolean contains(Edge edge)
{
return edges.containsKey(new EdgeKey(edge));
}
/**
* Gets the <code>Nodes</code> contained in the <code>Graph</code>
* as an array.
* @return An array containing the <code>Nodes</code> in the <code>Graph</code>.
*/
public Node[] getNodes()
{
Object [] array = nodes.keySet().toArray();
Node [] nodeArray = new Node [array.length];
System.arraycopy(array, 0, nodeArray, 0, array.length);
return nodeArray;
}
/**
* Gets the <code>Edges</code> contained in the <code>Graph</code> as an array.
* @return An array containing the <code>Edges</code> in the <code>Graph</code>.
*/
public Edge[] getEdges()
{
Object [] array = edges.values().toArray();
Edge [] edgeArray = new Edge [array.length];
System.arraycopy(array, 0, edgeArray, 0, array.length);
return edgeArray;
}
public class EdgeKey
{
private Node tailNode;
private Node headNode;
public EdgeKey(Edge edge)
{
this.tailNode = edge.getTailNode();
this.headNode = edge.getHeadNode();
}
public EdgeKey(Node tailNode, Node headNode)
{
this.tailNode = tailNode;
this.headNode = headNode;
}
public int hashCode()
{
return tailNode.hashCode() * 13 + headNode.hashCode() * 37;
}
public boolean equals(Object obj)
{
if(obj.getClass().equals(this.getClass()) == false)
{
return false;
}
EdgeKey key = (EdgeKey)obj;
if(key.tailNode.equals(tailNode) && key.headNode.equals(headNode))
{
return true;
}
else
{
return false;
}
}
}
}

View file

@ -0,0 +1,115 @@
package de.unibremen.informatik.hets.graphviz;
//import uk.ac.man.cs.mig.util.graph.graph.Node;
import java.awt.*;
import java.awt.geom.Ellipse2D;
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: Jan 15, 2004<br><br>
*
* matthew.horridge@cs.man.ac.uk<br>
* www.cs.man.ac.uk/~horridgm<br><br>
*
*/
public class Node
{
private Object userObject;
private String label;
private Ellipse2D.Double ellipse;
private Point pos;
/**
* Constructs a <code>Node</code> that represents the specified object.
* @param userObject The object that the <code>Node</code> represents.
*/
public Node(Object userObject)
{
this.userObject = userObject;
ellipse = new Ellipse2D.Double();
pos = new Point();
}
public void setLabel(String l) {
label = l;
}
public String getLabel() {
return label;
}
/**
* Gets the userObject, previously set with <code>setUserObject(Object o)</code>
* @return The userObject, or <code>null</code> if no object has been set.
*/
public Object getUserObject()
{
return userObject;
}
/**
* Sets the (x,y) position of the <code>Node</code>.
* @param x The horizontal location.
* @param y The vertical location.
*/
public void setPosition(int x, int y)
{
int w = getSize().width;
int h = getSize().height;
pos.x = x;
pos.y = y;
ellipse.setFrame(x - w / 2, y - h / 2, w, h);
}
/**
* Gets the position of the <code>Node</code>.
* @return A <code>Point</code> containing the x,y position of the <code>Node</code>.
*/
public Point getPosition()
{
return pos;
}
/**
* Sets the <code>Node's</code> size.
* @param width The width of the <code>Node</code>.
* @param height The height of the <code>Node</code>.
*/
public void setSize(int width, int height)
{
int x = getPosition().x;
int y = getPosition().y;
ellipse.setFrame(x - width / 2, y - height / 2, width, height);//setLocation(x - width / 2, y - height / 2);
//rect.setSize(width, height);
}
/**
* Gets the size of the <code>Node</code>.
* @return A <code>Dimension</code> containing the width and height
* of the <code>Node</code>.
*/
public Dimension getSize()
{
return ellipse.getBounds().getSize();
}
/**
* Returns the <code>Shape</code> of the <code>Node</code>.
* @return The <code>Shape</code> of the <code>Node</code>.
*/
public Shape getShape()
{
return ellipse;
}
}

View file

@ -0,0 +1,301 @@
package de.unibremen.informatik.hets.graphviz;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
//import org.apache.log4j.Logger;
/*
import uk.ac.man.cs.mig.util.graph.controller.Controller;
import uk.ac.man.cs.mig.util.graph.controller.VisualisedObjectManager;
import uk.ac.man.cs.mig.util.graph.graph.Node;
import uk.ac.man.cs.mig.util.graph.layout.GraphLayoutEngine;
import uk.ac.man.cs.mig.util.graph.renderer.NodeRenderer;
*/
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: Jan 14, 2004<br><br>
*
* matthew.horridge@cs.visualisedObjectManager.ac.uk<br>
* www.cs.visualisedObjectManager.ac.uk/~horridgm<br><br>
*
*/
public class NodeRenderer
{
// private static Logger log = Logger.getLogger(DefaultNodeRenderer.class);
// private NodeLabelRenderer labelRenderer;
private static Color fillColor;
private static Color lineColor;
// private VisualisedObjectManager visualisedObjectManager;
private Polygon leftArrow = new Polygon();
private Polygon rightArrow = new Polygon();
private FontMetrics fontMetrics;
private static final int ARROW_SIZE = 5;
private static final int HORIZONTAL_PADDING = ARROW_SIZE * 2 + 10;
private static final int VERTICAL_PADDING = 15;
private Font labelFont;
// private Controller controller;
// private int layoutDirection = GraphLayoutEngine.LAYOUT_LEFT_TO_RIGHT;
private static Stroke lineStroke = new BasicStroke(2.0f);
// public NodeRenderer(Controller controller)
public NodeRenderer()
{
// this.controller = controller;
/*
if(controller.getVisualisedObjectManager() == null)
{
throw new NullPointerException("VisualisedObjectManager (in controller) must not be null");
}
*/
// visualisedObjectManager = controller.getVisualisedObjectManager();
JPanel pan = new JPanel();
Font font = pan.getFont();
labelFont = font.deriveFont(10.0f);
if(labelFont == null)
{
//log.error("Font is NULL!");
}
fontMetrics = pan.getFontMetrics(labelFont);
if(fontMetrics == null)
{
//log.error("Font metrics is NULL!");
}
/*
if(visualisedObjectManager == null)
{
throw new NullPointerException("DefaultNode renderer constructed before" +
"VisualisedObjectManager");
}
*/
// this.labelRenderer = labelRenderer;
fillColor = Color.YELLOW;
lineColor = Color.BLACK;
setupArrows();
}
protected Color getFillColor(Node node) {
return fillColor;
}
protected Color getLineColor(Node node) {
return lineColor;
}
protected Stroke getLineStroke() {
return lineStroke;
}
/**
* Generic shape renderer. Typically, the shape of the <code>Node</code>
* will be a <code>Rectangle</code> or an <code>Ellipse</code>.
* @param node The <code>Node</code> being rendered.
* @param g2 The Graphics2D object on to which the <code>Node</code> should be rendered.
* @param forPrinting A flag to indicate if the graphics are being drawn to produce an
* image for printing, or to draw onto the screen.
*/
public void renderNode(Graphics2D g2, Node node, boolean forPrinting, boolean drawDetail)
{
Shape sh = node.getShape();
// Only render if we are within the clip bounds
if(sh.intersects(g2.getClipBounds()))
{
// Fill the node
g2.setColor(getFillColor(node));
g2.fill(sh);
g2.setColor(getLineColor(node));
g2.setStroke(getLineStroke());
g2.draw(sh);
Object obj = node.getUserObject();
String label;
Point pos = node.getPosition();
if(drawDetail == true) {
//label = controller.getNodeLabelRenderer().getLabel(node);
label = node.getLabel();
// Draw expansion arrows
drawArrows(g2, sh, node.getUserObject());
// Draw text
Font f = g2.getFont();
g2.setFont(labelFont);
Rectangle2D labelBounds2D = g2.getFontMetrics().getStringBounds(label, g2);
Rectangle labelBounds = labelBounds2D.getBounds();
g2.drawString(label, pos.x - labelBounds.width / 2, pos.y + labelBounds.height / 3);
g2.setFont(f);
}
}
}
public Dimension getPreferredSize(Node node, Dimension size)
{
//String label = controller.getNodeLabelRenderer().getLabel(node);
String label = node.getLabel();
int width = SwingUtilities.computeStringWidth(fontMetrics, label);
int height = fontMetrics.getHeight();
if(size != null)
{
size.width = width + HORIZONTAL_PADDING;
size.height = height + VERTICAL_PADDING;
return size;
}
else
{
return new Dimension(width, height);
}
}
protected void drawArrows(Graphics2D g2, Shape nodeShape, Object userObject)
{
/*
if(controller.getGraphLayoutEngine().getLayoutDirection() != layoutDirection)
{
layoutDirection = controller.getGraphLayoutEngine().getLayoutDirection();
setupArrows();
}
if(layoutDirection == GraphLayoutEngine.LAYOUT_LEFT_TO_RIGHT)
{
if(visualisedObjectManager.getChildrenHiddenCount(userObject) > 0)
{
Rectangle rect = nodeShape.getBounds();
g2.translate(rect.x + rect.width, rect.y + rect.height / 2);
g2.fill(rightArrow);
g2.translate(-rect.x - rect.width, -rect.y - rect.height / 2);
}
if(visualisedObjectManager.getParentsHiddenCount(userObject) > 0)
{
Rectangle rect = nodeShape.getBounds();
g2.translate(rect.x, rect.y + rect.height / 2);
g2.fill(leftArrow);
g2.translate(-rect.x, -rect.y - rect.height / 2);
}
}
else
{
if(visualisedObjectManager.getChildrenHiddenCount(userObject) > 0)
{
Rectangle rect = nodeShape.getBounds();
g2.translate(rect.x + rect.width / 2, rect.y + rect.height);
g2.fill(rightArrow);
g2.translate(-rect.x - rect.width / 2, -rect.y - rect.height);
}
if(visualisedObjectManager.getParentsHiddenCount(userObject) > 0)
{
Rectangle rect = nodeShape.getBounds();
g2.translate(rect.x + rect.width / 2, rect.y);
g2.fill(leftArrow);
g2.translate(-rect.x - rect.width / 2, -rect.y);
}
}
*/
}
protected void setupArrows()
{/*
if(controller.getGraphLayoutEngine().getLayoutDirection() == GraphLayoutEngine.LAYOUT_LEFT_TO_RIGHT)
{
leftArrow.reset();
leftArrow.addPoint(ARROW_SIZE, -ARROW_SIZE);
leftArrow.addPoint(0, 0);
leftArrow.addPoint(ARROW_SIZE, ARROW_SIZE);
rightArrow.reset();
rightArrow.addPoint(-ARROW_SIZE, -ARROW_SIZE);
rightArrow.addPoint(0, 0);
rightArrow.addPoint(-ARROW_SIZE, ARROW_SIZE);
}
else
{*/
leftArrow.reset();
// Up Arrow
leftArrow.addPoint(-ARROW_SIZE, ARROW_SIZE);
leftArrow.addPoint(0, 0);
leftArrow.addPoint(ARROW_SIZE, ARROW_SIZE);
rightArrow.reset();
// Down arrow
rightArrow.addPoint(-ARROW_SIZE, -ARROW_SIZE);
rightArrow.addPoint(0, 0);
rightArrow.addPoint(ARROW_SIZE, -ARROW_SIZE);
// }
}
}

View file

@ -0,0 +1,199 @@
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
package de.unibremen.informatik.hets.graphviz;
import de.unibremen.informatik.hets.graphviz.dotparser.Token;
/**
* This exception is thrown when parse errors are encountered.
* You can explicitly create objects of this exception type by
* calling the method generateParseException in the generated
* parser.
*
* You can modify this class to customize your error reporting
* mechanisms so long as you retain the public fields.
*/
public class ParseException extends Exception {
/**
*
*/
private static final long serialVersionUID = -3846364971995374467L;
/**
* This constructor is used by the method "generateParseException"
* in the generated parser. Calling this constructor generates
* a new object of this type with the fields "currentToken",
* "expectedTokenSequences", and "tokenImage" set. The boolean
* flag "specialConstructor" is also set to true to indicate that
* this constructor was used to create this object.
* This constructor calls its super class with the empty string
* to force the "toString" method of parent class "Throwable" to
* print the error message in the form:
* ParseException: <result of getMessage>
*/
public ParseException(Token currentTokenVal,
int[][] expectedTokenSequencesVal,
String[] tokenImageVal
)
{
super("");
specialConstructor = true;
currentToken = currentTokenVal;
expectedTokenSequences = expectedTokenSequencesVal;
tokenImage = tokenImageVal;
}
/**
* The following constructors are for use by you for whatever
* purpose you can think of. Constructing the exception in this
* manner makes the exception behave in the normal way - i.e., as
* documented in the class "Throwable". The fields "errorToken",
* "expectedTokenSequences", and "tokenImage" do not contain
* relevant information. The JavaCC generated code does not use
* these constructors.
*/
public ParseException() {
super();
specialConstructor = false;
}
public ParseException(String message) {
super(message);
specialConstructor = false;
}
/**
* This variable determines which constructor was used to create
* this object and thereby affects the semantics of the
* "getMessage" method (see below).
*/
protected boolean specialConstructor;
/**
* This is the last token that has been consumed successfully. If
* this object has been created due to a parse error, the token
* followng this token will (therefore) be the first error token.
*/
public Token currentToken;
/**
* Each entry in this array is an array of integers. Each array
* of integers represents a sequence of tokens (by their ordinal
* values) that is expected at this point of the parse.
*/
public int[][] expectedTokenSequences;
/**
* This is a reference to the "tokenImage" array of the generated
* parser within which the parse error occurred. This array is
* defined in the generated ...Constants interface.
*/
public String[] tokenImage;
/**
* This method has the standard behavior when this object has been
* created using the standard constructors. Otherwise, it uses
* "currentToken" and "expectedTokenSequences" to generate a parse
* error message and returns it. If this object has been created
* due to a parse error, and you do not catch it (it gets thrown
* from the parser), then this method is called during the printing
* of the final stack trace, and hence the correct error message
* gets displayed.
*/
public String getMessage() {
if (!specialConstructor) {
return super.getMessage();
}
String expected = "";
int maxSize = 0;
for (int i = 0; i < expectedTokenSequences.length; i++) {
if (maxSize < expectedTokenSequences[i].length) {
maxSize = expectedTokenSequences[i].length;
}
for (int j = 0; j < expectedTokenSequences[i].length; j++) {
expected += tokenImage[expectedTokenSequences[i][j]] + " ";
}
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
expected += "...";
}
expected += eol + " ";
}
String retval = "Encountered \"";
Token tok = currentToken.next;
for (int i = 0; i < maxSize; i++) {
if (i != 0) retval += " ";
if (tok.kind == 0) {
retval += tokenImage[0];
break;
}
retval += add_escapes(tok.image);
tok = tok.next;
}
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
retval += "." + eol;
if (expectedTokenSequences.length == 1) {
retval += "Was expecting:" + eol + " ";
} else {
retval += "Was expecting one of:" + eol + " ";
}
retval += expected;
return retval;
}
/**
* The end of line string for this machine.
*/
protected String eol = System.getProperty("line.separator", "\n");
/**
* Used to convert raw characters to their escaped version
* when these raw version cannot be used as part of an ASCII
* string literal.
*/
protected String add_escapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
}

View file

@ -0,0 +1,272 @@
/**
* User: matthewhorridge<br>
* The Univeristy Of Manchester<br>
* Medical Informatics Group<br>
* Date: May 7, 2004<br><br>
* <p/>
* matthew.horridge@cs.man.ac.uk<br>
* www.cs.man.ac.uk/~horridgm<br><br>
*/
options
{
STATIC = false;
}
PARSER_BEGIN(DotParser)
package de.unibremen.informatik.hets.graphviz.dotparser;
import java.io.*;
import java.util.*;
import de.unibremen.informatik.hets.graphviz.DotParameterSetter;
import de.unibremen.informatik.hets.graphviz.ParseException;
import de.unibremen.informatik.hets.graphviz.DotPreParser;
import de.unibremen.informatik.hets.graphviz.Graph;
public class DotParser
{
private static boolean gotGraphBB;
private static DotParameterSetter paramSetter;
public static void parse(DotParameterSetter setter, InputStream inputStream) throws ParseException
{
paramSetter = setter;
gotGraphBB = false;
String s = DotPreParser.preParse(inputStream);
try {
InputStream iStream = new ByteArrayInputStream(s.getBytes("UTF-8"));
DotParser parser = new DotParser(iStream, "UTF-8");
parser.start();
}
catch (UnsupportedEncodingException e) {
throw new ParseException("Cannot parse the input - bad encoding");
}
}
public static void setGraphAttribute(String name, String value)
{
if(name.equals("bb"))
{
if(gotGraphBB == false)
{
paramSetter.setGraphAttribute(name, removeQuotes(value));
gotGraphBB = true;
}
}
else
{
paramSetter.setGraphAttribute(name, removeQuotes(value));
}
}
public static void setNodeAttribute(String nodeID, String name, String value)
{
paramSetter.setNodeAttribute(removeQuotes(nodeID), name, removeQuotes(value));
}
public static void setEdgeAttribute(String tailNode, String headNode, String name, String value)
{
paramSetter.setEdgeAttribute(removeQuotes(tailNode), removeQuotes(headNode), name, removeQuotes(value));
}
protected static String removeQuotes(String s)
{
if(s.charAt(0) == '\"' && s.charAt(s.length() - 1) == '\"')
{
return s.substring(1, s.length() - 1);
}
else
{
return s;
}
}
}
PARSER_END(DotParser)
SKIP: {" "}
SKIP: {"\n" | "\r" | "\t"}
TOKEN: {<KWSTRICT: "strict">}
TOKEN: {<KWGRAPH: "graph">}
TOKEN: {<KWDIGRAPH: "digraph">}
TOKEN: {<KWSUBGRAPH: "subgraph">}
TOKEN: {<KWNODE: "node">}
TOKEN: {<KWEDGE: "edge">}
TOKEN: {<SQOPENPAR: "[">}
TOKEN: {<SQCLOSEPAR: "]">}
TOKEN: {<EQUALS: "=">}
TOKEN: {<COMMA: ",">}
TOKEN: {<EDGEOP: "->">}
TOKEN: {<ID: ("\""(~["\""])*"\"") | (<ALPHANUM> (<ALPHANUM> | "_")*)>}
TOKEN: {<#ALPHA: ["a"-"z"] | ["A"-"Z"] | ["\u00A1"-"\uFFFF"]>}
TOKEN: {<#NUM: ["0"-"9"]>}
TOKEN: {<#ALPHANUM: <ALPHA>|<NUM>>}
void start():
{
}
{
graph()
}
void graph():
{
}
{
(<KWSTRICT>)?
(<KWGRAPH> | <KWDIGRAPH>)
(<ID>)?
"{"
(stmt())+
"}"
}
void stmt():
{
}
{
(node_or_edge_stmt() | attr_stmt() | subgraph()) (";")*
}
void node_or_edge_stmt():
{
String id1, id2 = null;
String name = "";
String value = "";
}
{
id1 = ID() // Node ID
(
<EDGEOP>
id2 = ID()
<SQOPENPAR> // Edge
(
(name = ID()
(
(
<EQUALS>
value = ID()
)*
(<COMMA>)?
)
{
setEdgeAttribute(id1, id2, name, value);
name = "";
value = "";
}
)*
)
<SQCLOSEPAR>
|
<SQOPENPAR> // Node
(
(name = ID()
(
(
<EQUALS>
value = ID()
)*
(<COMMA>)?
)
{
setNodeAttribute(id1, name, value);
name = "";
value = "";
}
)*
)
<SQCLOSEPAR>
)
}
void attr_stmt():
{
String name = "";
String value = "";
final int TYPE_GRAPH = 0;
final int TYPE_NODE = 1;
final int TYPE_EDGE = 2;
int TYPE = TYPE_GRAPH;
}
{
(
<KWGRAPH>
{
TYPE = TYPE_GRAPH;
}
|
<KWNODE>
{
TYPE = TYPE_NODE;
}
|
<KWEDGE>
{
TYPE = TYPE_EDGE;
}
)
<SQOPENPAR>
(
(name = ID()
(
(
<EQUALS>
value = ID()
)
(<COMMA>)?
)
{
if(TYPE == TYPE_GRAPH)
{
setGraphAttribute(name, value);
}
name = "";
value = "";
}
)*
)
<SQCLOSEPAR>
}
void subgraph():
{
}
{
(<KWSUBGRAPH>(ID()) "{" (stmt())+ "}")
}
String ID():
{
Token t;
}
{
t = <ID>
{
return t.image;
}
}

View file

@ -0,0 +1,66 @@
package de.unibremen.informatik.hets.protege;
import java.io.File;
import de.unibremen.informatik.hets.graphviz.Graph;
import de.unibremen.informatik.hets.graphviz.DotGraphLayoutEngine;
import de.unibremen.informatik.hets.graphviz.NodeRenderer;
import de.unibremen.informatik.hets.graphviz.EdgeRenderer;
import de.unibremen.informatik.hets.graphviz.Node;
import de.unibremen.informatik.hets.graphviz.Edge;
import org.protege.editor.core.ui.view.ViewComponent;
import javax.swing.*;
import java.awt.*;
public class HetsVizView extends ViewComponent {
Graph g;
@Override
public void initialise() throws Exception {
}
@Override
public void dispose() throws Exception {
}
public void setDot(File file) {
DotGraphLayoutEngine engine = new DotGraphLayoutEngine();
g = engine.layoutGraph(file);
}
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D g2 = (Graphics2D) graphics;
Shape clip = g2.getClip();
g2.setColor(Color.WHITE);
g2.fill(clip);
g2.scale(1.0, 1.0);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (g == null) {
return;
}
NodeRenderer noderenderer = new NodeRenderer();
EdgeRenderer edgerenderer = new EdgeRenderer();
Dimension size = new Dimension();
Node[] nodes = g.getNodes();
for (int i = 0; i < nodes.length; i++) {
noderenderer.getPreferredSize(nodes[i], size);
nodes[i].setSize(size.width, size.height);
noderenderer.renderNode(g2, nodes[i], true, true);
}
Edge[] edges = g.getEdges();
for (int i = 0; i < edges.length; i++) {
edgerenderer.renderEdge(g2, edges[i], true, true);
}
}
}