addition of hetsview component
This commit is contained in:
parent
511507f82d
commit
a1a8882d14
16 changed files with 2609 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -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
|
||||||
|
|
|
@ -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">
|
||||||
|
|
17
plugin.xml
17
plugin.xml
|
@ -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>
|
||||||
|
|
15
resources/viewconfig-hetsviz.xml
Normal file
15
resources/viewconfig-hetsviz.xml
Normal 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>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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() + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
61
src/de/unibremen/informatik/hets/graphviz/DotPreParser.java
Normal file
61
src/de/unibremen/informatik/hets/graphviz/DotPreParser.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
107
src/de/unibremen/informatik/hets/graphviz/DotProcess.java
Normal file
107
src/de/unibremen/informatik/hets/graphviz/DotProcess.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
305
src/de/unibremen/informatik/hets/graphviz/Edge.java
Normal file
305
src/de/unibremen/informatik/hets/graphviz/Edge.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
213
src/de/unibremen/informatik/hets/graphviz/EdgeRenderer.java
Normal file
213
src/de/unibremen/informatik/hets/graphviz/EdgeRenderer.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
293
src/de/unibremen/informatik/hets/graphviz/Graph.java
Normal file
293
src/de/unibremen/informatik/hets/graphviz/Graph.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
115
src/de/unibremen/informatik/hets/graphviz/Node.java
Normal file
115
src/de/unibremen/informatik/hets/graphviz/Node.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
301
src/de/unibremen/informatik/hets/graphviz/NodeRenderer.java
Normal file
301
src/de/unibremen/informatik/hets/graphviz/NodeRenderer.java
Normal 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);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
199
src/de/unibremen/informatik/hets/graphviz/ParseException.java
Normal file
199
src/de/unibremen/informatik/hets/graphviz/ParseException.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
272
src/de/unibremen/informatik/hets/graphviz/dotparser/DotParser.jj
Normal file
272
src/de/unibremen/informatik/hets/graphviz/dotparser/DotParser.jj
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
66
src/de/unibremen/informatik/hets/protege/HetsVizView.java
Normal file
66
src/de/unibremen/informatik/hets/protege/HetsVizView.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue