/**
*
*/
package agg.layout.evolutionary;
import java.awt.Dimension;
import java.awt.Point;
import java.util.List;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Random;
import agg.editor.impl.EdGraph;
import agg.editor.impl.EdNode;
import agg.editor.impl.EdArc;
import agg.xt_basis.Arc;
import agg.xt_basis.Type;
/**
* @author Dennis
*
*/
public class EvolutionaryGraphLayout {
private boolean jpgOutput;
private boolean enabled;
private Dimension panel;
private boolean panelChangable;
private final LayoutMetrics lmetric;
private EdGraph oldedgraph;
private int gnrlEdgeLngth;
private int temperature;
private boolean usePattern;
private boolean frozenPos;
private boolean centre;
private boolean writeMetrics;
private int iters, nodeIntersctnIters,
edgeIntersctnIters;
private int overlapscnt;
private final Hashtable<Type, Vector<LayoutPattern>> layoutPatterns;
private final Hashtable<LayoutNode, Type> layoutNode2Type;
// private boolean freezingOldNode, freezingOldEdge;
private final Random random = new Random();
/**
* konstruktor fuer den Layouter
*
* @param temp
* temp gibt eine begrenzug fuer die bewegung einer node in einem
* iterationsschritt an, wird hier als temperatur bezeichnet....
*
*/
public EvolutionaryGraphLayout(final int temp, final Dimension panel) {
this.temperature = temp;
this.panel = panel;
this.panelChangable = true;
this.lmetric = new LayoutMetrics();
this.oldedgraph = null;
this.jpgOutput = true;
this.enabled = false;
this.usePattern = false;
this.frozenPos = false;
this.centre = false;
this.writeMetrics = true;
this.iters = 100;
this.nodeIntersctnIters = 1;
this.edgeIntersctnIters = 50;
this.overlapscnt = 0;
this.gnrlEdgeLngth = 200;
this.layoutPatterns = new Hashtable<Type, Vector<LayoutPattern>>();
this.layoutNode2Type = new Hashtable<LayoutNode, Type>();
}
public void setEnabled(final boolean b) {
this.enabled = b;
}
public boolean isEnabled() {
return this.enabled;
}
/**
* gibt die anziehungskraefte zwischen nodes wieder momentan wird die
* eigenschaft der kante zwischen den nodes nicht beruecksichtigt. TODO
* Kanteneigenschaften beruecksichtigen
*
* @param d
* distanz zwischen 2 nodes
* @param z
* Zone um die nodes in der keine andere node liegen soll
* @return
*/
// wird nicht mehr benutzt.
private int getAttrForce(final int d, final int z) {
return (d * d) / z;
}
/**
* gibt die abstossenden Kraefte zwischen 2 nodes wieder diese sind
* unabhaengig davon, ob die nodes durch eine kante(arc) verbunden sind,
* oder nicht.
*
* @param d
* distanz zwischen 2 nodes
* @param z
* zone um die nodes in der keine andere node liegen soll
* @return
*/
private int getRepulseForce(final int d, final int z) {
return (z * z) / Math.abs(d);
}
private int cool(final int temp, final int it) {
// hiermit wird temp reduziert, und zwar in jedem iterationsschritt
// etwas weniger als im vorherigen
// angefangen mit it+2, weil it ja im ersten schritt 0 ist, so wird
// also t im ersten schritt halbiert, dann der rest um ein drittel
// reduziert, dann um ein viertel........
return temp - (temp / (it + 2));
}
/**
* reduziert die bewegungsfreiheit fuer einen knoten entsprechend seinem
* Alter
*
* @param temp
* Ausgangstemperatur / Bewegungsfreiheit
* @param age
* Alter des betrachteten Knotens
* @param gage
* Alter des Gesamtgraphen
* @return reduzierte Temperatur / Bewegungsfreiheit
*/
private int reduceTempByAge(final int temp, final int age, final int gage) {
int ret;
if (gage == 0) {
ret = temp;
} else {
ret = temp - (temp / (gage - age + 1));
}
return ret;
}
public void createInheritancePattern(final Vector<Arc> inheritanceArcs) {
for (int i = 0; i < inheritanceArcs.size(); i++) {
final Arc inharc = inheritanceArcs.get(i);
// String inhTypeName = inharc.getSource().getType().getName()
// + "-INHERITS-" + inharc.getTarget().getType().getName();
final Vector<LayoutPattern> v = getLayoutPatternsForType(inharc.getType());
if (!v.isEmpty()) {
v.clear();
}
createLayoutPattern("ver_tree", "edge", inharc.getType(), 'y', -1);
createLayoutPattern("edge_length", "edge", inharc.getType(), 150);
}
}
private Vector<LayoutPattern> getInheritancePattern(final EdArc edge) {
if (edge.getBasisArc().isInheritance()) {
// String inhTypeName = edge.getBasisArc().getSource().getType()
// .getName()
// + "-INHERITS-"
// + edge.getBasisArc().getTarget().getType().getName();
return getLayoutPatternsForType(edge.getBasisArc().getType());
}
return null;
}
public void layout(final EdGraph egraph,
final List<EdNode> nodes,
final List<EdArc> arcs) {
layout(egraph, nodes, arcs, this.iters);
}
public void layout(final EdGraph egraph,
final List<EdNode> nodes,
final List<EdArc> arcs,
final int itrs) {
final Vector<LayoutNode> lnodes = getLayoutNodes(nodes);
final Vector<LayoutArc> larcs = getLayoutArcs(arcs);
int temp = this.temperature;
for (int i = 0; i < itrs; i++) {
// System.out.println("iteration: "+i+" this.temperature: "+ temp);
// abstossende kraefte:
calcNodeRepulse(lnodes);
// anziehungskraefte nur fuer verbundene nodes berechnen
for (int j = 0; j < larcs.size(); j++) {
final LayoutArc larc = larcs.get(j);
if (!larc.getEdArc().isLine()) {
continue;
}
final LayoutNode lnodev = ((EdNode) larc.getEdArc().getSource()).getLNode();
final LayoutNode lnodeu = ((EdNode) larc.getEdArc().getTarget()).getLNode();
final int deltax = lnodev.getAkt().x - lnodeu.getAkt().x;
final int deltay = lnodev.getAkt().y - lnodeu.getAkt().y;
// abfragen um division durch 0 zu vermeiden, wenn deltax oder
// deltay 0 sind, aendert sich nix an der distanz
if (deltax != 0) {
lnodev.setDistX(lnodev.getDistX()
- ((deltax / Math.abs(deltax)) * getAttrForce(
deltax, lnodev.getZone())));
lnodeu.setDistX(lnodeu.getDistX()
+ ((deltax / Math.abs(deltax)) * getAttrForce(
deltax, lnodeu.getZone())));
}
if (deltay != 0) {
lnodev.setDistY(lnodev.getDistY()
- ((deltay / Math.abs(deltay)) * getAttrForce(
deltay, lnodev.getZone())));
lnodeu.setDistY(lnodeu.getDistY()
+ ((deltay / Math.abs(deltay)) * getAttrForce(
deltay, lnodeu.getZone())));
}
}
// kraefte in positionsaenderung umrechnen
calcDistToPos(arcs, lnodes, temp, egraph.getGraphGen());
temp = cool(temp, i);
// wenn temp 0 ist, ist keine positionsaenderung mehr moeglich, also
// muss auch nicht weiter berechnet werden
if (temp == 0) {
break;
}
}
egraph.setGraphDim(this.panel);
// die neuen Layoutinfos aus dem Layoutnodes in die EdNodes uebertragen.
egraph.updateNodePosLtoE(nodes);
}
/**
* berechnet die positionsaenderung von knoten anhand der abstossenden
* kraefte die zwischen allen knoten bestehen.
*
* @param lnodes
*/
private void calcNodeRepulse(final Vector<LayoutNode> lnodes) {
for (int j = 0; j < lnodes.size(); j++) {
final LayoutNode lnodev = lnodes.get(j);
if ((!this.usePattern && (lnodev.isFrozenByDefault() && this.frozenPos))
|| isFrozen(lnodev)) {// type pattern check
continue;
}
lnodev.setDistX(0);
lnodev.setDistY(0);
// bestimmung der kraefte anteilig in x und y richtung
for (int k = 0; k < lnodes.size(); k++) {
final LayoutNode lnodeu = lnodes.get(k);
// keine werte fuer identische lnodes berechnen
if (lnodev.equals(lnodeu)) {
continue;
}
// if(!this.usepattern && (lnodeu.isFrozenAsDefault() && this.frozenPos))
// continue;
// else if(isFrozen(lnodeu)) // type pattern check
// continue;
final int deltax = lnodev.getAkt().x - lnodeu.getAkt().x;
final int deltay = lnodev.getAkt().y - lnodeu.getAkt().y;
// abfragen um division durch 0 zu vermeiden, wenn deltax oder
// deltay 0 sind, aendert sich nix an der distanz
// bloeder denkfehler: in vielen faellen muss sich dann die
// dist, also die gewuenschte bewegung, einen wert !=0 haben, da
// die knoten auf der selben pos liegen
// int distx = 0, disty = 0;
if (deltax != 0) {
// distx = lnodev.getDistX() +
// ((deltax/Math.abs(deltax))*getRepulseForce(deltax,lnodev.getZone()));
lnodev.setDistX(lnodev.getDistX()
+ ((deltax / Math.abs(deltax)) * getRepulseForce(
deltax, lnodev.getZone())));
}
if (deltay != 0) {
// disty = lnodev.getDistY() +
// ((deltay/Math.abs(deltay))*getRepulseForce(deltay,lnodev.getZone()));
lnodev.setDistY(lnodev.getDistY()
+ ((deltay / Math.abs(deltay)) * getRepulseForce(
deltay, lnodev.getZone())));
}
// test minus bereich
// if(distx < 0) distx = distx * (-1);
// if(disty < 0) disty = disty * (-1);
// lnodev.setDistX(distx);
// lnodev.setDistY(disty);
if (deltax == 0 && deltay == 0) {
// wenn die knoten auf der selben position liegen
// zuefaellige distx und disty aenderung
// gibt sicher noch ne bessere moeglichkeit???
// long l = Double.doubleToLongBits(Math.random());
// int r = ((Long)l).intValue()%200;
int r = this.random.nextInt(this.panel.width) % 200;
lnodev.setDistX(lnodev.getDistX() + r);
lnodev.setDistY(lnodev.getDistY() - r);
// test minus bereich
// disty = lnodev.getDistY() - r;
// if(disty < 0) disty = disty * (-1);
// lnodev.setDistY(disty);
}
}
}
}
private void calcDistToPos(final List<EdArc> arcs,
final Vector<LayoutNode> lnodes,
final int temp,
final int gage) {
int newx, newy, minx, miny, age, akttemp;
for (int j = 0; j < lnodes.size(); j++) {
final LayoutNode lnodev = lnodes.get(j);
if ((!this.usePattern && (lnodev.isFrozenByDefault() && this.frozenPos))
|| isFrozen(lnodev)) {
continue;
}
newx = lnodev.getAkt().x;
newy = lnodev.getAkt().y;
minx = 0;
miny = 0;
age = lnodev.getAge();
akttemp = reduceTempByAge(temp, age, gage);
if (lnodev.getDistX() != 0) {
// newx = lnodev.getAkt().x +
// ((lnodev.getDistX()/Math.abs(lnodev.getDistX()))*Math.min(Math.abs(lnodev.getDistX()),temp));
minx = Math.min(Math.abs(lnodev.getDistX()), akttemp);
if (lnodev.getDistX() >= 0) {
newx = newx + minx;
} else {
newx = newx - minx;
}
}
if (lnodev.getDistY() != 0) {
// newy = lnodev.getAkt().y +
// ((lnodev.getDistX()/Math.abs(lnodev.getDistY()))*Math.min(Math.abs(lnodev.getDistY()),temp));
miny = Math.min(Math.abs(lnodev.getDistY()), akttemp);
if (lnodev.getDistY() >= 0) {
newy = newy + miny;
} else {
newy = newy - miny;
}
}
// System.out.println("min(distx,temp): "+minx+" min(disty,temp):
// "+miny+" newx: "+newx+" newy:"+newy);
// simpler ansatz um zu verhindern,
// das die nodes aus dem Panel wandern
// vermutlich noch zu verbessern
// // keine negativen werte
if ((newx - lnodev.getEdNode().getWidth()/2) <= 0)
newx = Math.max(newx, lnodev.getEdNode().getWidth());
if ((newy - lnodev.getEdNode().getHeight()/2) <= 0)
newy = Math.max(newy, lnodev.getEdNode().getHeight());
// // keine werte die groesser sind als die panelbreite
// newx =
// Math.min(newx,this.panel.width-lnodev.getEdNode().getWidth()*2);
// // keine werte, die groesser als die Panelhoehe sind
// newy =
// Math.min(newy,this.panel.height-lnodev.getEdNode().getHeight()*2);
//
// //System.out.println("aktx: "+lnodev.getAkt().x+" akty:
// "+lnodev.getAkt().y+" distx: "+lnodev.getDistX()+" disty:
// "+lnodev.getDistY()+" newx: "+newx+" newy: "+newy);
// lnodev.setOpt(new Point(newx,newy));
// lnodev.setAkt(new Point(newx,newy));
// //TODO eventuell noch an die panelgroesse anpassen.....
// check min, max position, change if needed
Point newp = getRandomPosIfNeeded(newx, newy, lnodev);
lnodev.setOpt(newp);
lnodev.setAkt(newp);
}
if (this.usePattern) {
for (int i = 0; i < arcs.size(); i++) {
final EdArc arc = arcs.get(i);
Vector<LayoutPattern> patterns = null;
if (arc.isElementOfTypeGraph())
patterns = getInheritancePattern(arc);
if (patterns == null)
patterns = getLayoutPatternsForType(arc.getType()
.getBasisType());
for (int p = 0; p < patterns.size(); p++) {
// lp =
// /*eg.getGraGra().*/getLayoutPatternForTypeName(arc.getTypename());
final LayoutPattern lp = patterns.get(p);
// System.out.println("LayoutPatternForTypeName
// "+lp.getEffectedEdgeType());
if (lp != null && lp.isEdgePattern()) {
final LayoutNode source = ((EdNode) arc.getSource()).getLNode();
final LayoutNode target = ((EdNode) arc.getTarget()).getLNode();
if (lp.isXOffset()) {
if (lp.getOffset() > 0) {// target muss
// groesseres x haben
if (!isFrozen(target)) {
newx = Math.max(target.getAkt().x, source
.getAkt().x + 4);
newy = target.getAkt().y;
target.setAkt(new Point(newx, newy));
} else if (!isFrozen(source)) {
newx = Math.min(target.getAkt().x - 1,
source.getAkt().x);
newy = source.getAkt().y;
source.setAkt(new Point(newx, newy));
}
} else {// offset kleiner null -> target muss
// kleineres x haben
if (!isFrozen(source)) {
newx = Math.max(target.getAkt().x + 1,
source.getAkt().x);
newy = source.getAkt().y;
source.setAkt(new Point(newx, newy));
} else if (!isFrozen(target)) {
newx = Math.min(target.getAkt().x, source
.getAkt().x - 4);
newy = target.getAkt().y;
target.setAkt(new Point(newx, newy));
}
}
}// else
if (lp.isYOffset()) {
if (lp.getOffset() > 0) {// target muss
// groesseres y haben
if (!isFrozen(target)) {
newy = Math.max(target.getAkt().y, source
.getAkt().y + 4);
newx = target.getAkt().x;
target.setAkt(new Point(newx, newy));
} else if (!isFrozen(source)) {
newy = Math.min(target.getAkt().y - 1,
source.getAkt().y);
newx = source.getAkt().x;
source.setAkt(new Point(newx, newy));
}
} else {// offset kleiner null -> target muss
// kleineres x haben
if (!isFrozen(source)) {
newy = Math.max(target.getAkt().y + 1,
source.getAkt().y);
newx = source.getAkt().x;
source.setAkt(new Point(newx, newy));
} else if (!isFrozen(target)) {
newy = Math.min(target.getAkt().y, source
.getAkt().y - 4);
newx = target.getAkt().x;
target.setAkt(new Point(newx, newy));
}
}
}
}
}
}
}
}
// arcLayout
public void layoutByArcLength(final EdGraph eg,
final List<EdNode> nodes,
final List<EdArc> arcs) {
// layoutByArcLength(eg, iterations, this.temperature);
layoutByArcLength(eg, nodes, arcs, this.edgeIntersctnIters, this.temperature);
}
/**
* berechnet ein layout fuer den graphen nur anhand der aktuellen und
* bevorzugten Kantenlaengen
*
* @param eg
* Graph zu layout
* @param nodes
* sichtbare Knoten in dem Graphen
* @param arcs
* Kanten mit Soure und Target in sichtbaren Knoten
* @param itrs
* Anzahl der Iterationen
* @param temp
* "temperatur" gibt an, wie stark sich die position eines Knoten
* pro berechnungsschritt aendern darf
*/
// arcLayout
public boolean layoutByArcLength(final EdGraph eg,
final List<EdNode> nodes,
final List<EdArc> arcs,
final int itrs,
final int temp) {
// wenn der graph keine kanten enthaelt, ist diese methode irrelevant:
if (arcs.size() == 0) {
return true;
}
int age, akttemp;
final int gage = eg.getGraphGen();
// System.out.println("Layouter.layoutByArcLength ...");
// aktuelle laenge aller arcs berechnen
for (int i = 0; i < arcs.size(); i++) {
final EdArc arc = arcs.get(i);
arc.getLArc().calcAktLength();
arc.getLArc().resetUsed();
}
int index;
int max, abw, xchange, ychange, sxchange, sychange, txchange, tychange, sxnew, synew, txnew, tynew;
boolean layoutDone = false;
for (int i = 0; i < itrs; i++) {
// arc mit groesster abweichung bestimmen
max = 0;
index = -1;
for (int j = 0; j < arcs.size(); j++) {
final EdArc edarc = arcs.get(j);
final LayoutArc larc = edarc.getLArc();
int prefLength = larc.getPrefLength();
LayoutPattern lpat = getLayoutPatternForType(edarc
.getBasisArc().getType(), "edge_length");
if (lpat != null && lpat.getLength() > 0) {
prefLength = lpat.getLength();
}
// System.out.println("prefLength: "+prefLength);
abw = Math.abs(prefLength - larc.getAktLength());
// vorzeichen interessiert hier nicht,sondern nur das ausmass
// der abweichung.
// evtl spaeter abweichungen in richtung zu kurz schwerer
// gewichten als zu lang!?
if ((abw / (larc.getUsed() + 1)) > max) {
// somit wird vermieden, das kanten immer wieder betrachtet
// werden,
// aber nicht oder nur sehr wenig geaendert werden koennen
// (neue kanten zwischen alten knoten)
max = abw;
index = j;
}
}
if (index == -1) {
continue;
}
final EdArc arc = arcs.get(index);
final LayoutArc larc = arc.getLArc();
larc.incUsed();
// System.out.println("max: "+max+" arclengthx:
// "+larc.getXLength()+" arclengthy: "+larc.getYLength());
if (max < 20) {// bei so kleinen abweichungen lohnt der aufwand
// nicht mehr, evtl den wert noch aendern
// System.out.println("iter i: "+i+" max arc-length abweichung:
// "+max+" arclengthx: "+larc.getXLength()+" arclengthy:
// "+larc.getYLength());
break;
}
// neue Positionen fuer die endknoten berechnen
final LayoutNode source = ((EdNode) arc.getSource()).getLNode();
final LayoutNode target = ((EdNode) arc.getTarget()).getLNode();
int prefLength = larc.getPrefLength();
LayoutPattern lpat = getLayoutPatternForType(arc.getBasisArc()
.getType(), "edge_length");
if (lpat != null && lpat.getLength() > 0) {
prefLength = lpat.getLength();
}
abw = larc.getAktLength() - prefLength; // larc.getPrefLength();//abw
// ist positiv, wenn die
// aktuelle laenge groesser
// als die bevorzugte ist
// aenderungen in x und y richtung berechnen um die abweichung
// auszugleichen
if (larc.getXLength() != 0 && larc.getYLength() != 0) {
// xc = ((abw*abw)/4)*larc.getXLength()*larc.getXLength();
// xy =
// (larc.getXLength()*larc.getXLength())+(larc.getYLength()*larc.getYLength());
// System.out.println("xc: "+xc+" xy: "+xy);
// xchange = (int)Math.sqrt(xc/xy);
// ychange = (larc.getYLength()*xchange)/larc.getXLength();
xchange = Math.abs(((abw / 2) * larc.getXLength())
/ larc.getAktLength());
ychange = Math.abs(((abw / 2) * larc.getYLength())
/ larc.getAktLength());
} else {
if (larc.getXLength() == 0) {
xchange = 0;
ychange = Math.abs(abw / 2);
} else {
xchange = Math.abs(abw / 2);
ychange = 0;
}
}
// //System.out.println("Akt-LEngth: "+larc.getAktLength()+"
// Abweichung: "+abw+" xchange: "+xchange+" ychange: "+ychange);
// positionsaenderungen werden durch temperatur beschraenkt und mit
// dem vorzeichen von abw versehen
age = source.getAge();
if (!(this.frozenPos && source.isFrozenByDefault())) {
akttemp = reduceTempByAge(temp, age, gage);
}
else {
akttemp = temp;
}
sxchange = Math.min(xchange, akttemp) * (abw / Math.abs(abw));
sychange = Math.min(ychange, akttemp) * (abw / Math.abs(abw));
age = target.getAge();
if (!(this.frozenPos && target.isFrozenByDefault())) {
akttemp = reduceTempByAge(temp, age, gage);
}
else {
akttemp = temp;
}
akttemp = reduceTempByAge(temp, age, gage);
txchange = Math.min(xchange, akttemp) * (abw / Math.abs(abw));
tychange = Math.min(ychange, akttemp) * (abw / Math.abs(abw));
if (source.getAkt().x <= target.getAkt().x) {
sxnew = source.getAkt().x + sxchange;
txnew = target.getAkt().x - txchange;
} else {
sxnew = source.getAkt().x - sxchange;
txnew = target.getAkt().x + txchange;
}
if (source.getAkt().y <= target.getAkt().y) {
synew = source.getAkt().y + sychange;
tynew = target.getAkt().y - tychange;
} else {
synew = source.getAkt().y - sychange;
tynew = target.getAkt().y + tychange;
}
// //nicht in negative bereiche kommen...
// sxnew = Math.max(sxnew,source.getEdNode().getWidth());
// synew = Math.max(synew,source.getEdNode().getHeight());
// txnew = Math.max(txnew,target.getEdNode().getWidth());
// tynew = Math.max(tynew,target.getEdNode().getHeight());
// // nicht aus dem Panel herausgehen:
// sxnew =
// Math.min(sxnew,this.panel.width-source.getEdNode().getWidth()*2);
// synew =
// Math.min(synew,this.panel.height-source.getEdNode().getHeight()*2);
// txnew =
// Math.min(txnew,this.panel.width-target.getEdNode().getWidth()*2);
// tynew =
// Math.min(tynew,this.panel.height-target.getEdNode().getHeight()*2);
// test
if (!(this.frozenPos && source.isFrozenByDefault())) {
Point newsp = getRandomPosIfNeeded(sxnew, synew, source);
sxnew = newsp.x;
synew = newsp.y;
}
if (!(this.frozenPos && target.isFrozenByDefault())) {
Point newtp = getRandomPosIfNeeded(txnew, tynew, target);
txnew = newtp.x;
tynew = newtp.y;
}
if (this.usePattern) {
Vector<LayoutPattern> patterns = null;
if (arc.isElementOfTypeGraph()) {
patterns = getInheritancePattern(arc);
}
if (patterns == null) {
patterns = getLayoutPatternsForType(arc.getType()
.getBasisType());
}
for (int p = 0; p < patterns.size(); p++) {
//final LayoutPattern lp =
// /*eg.getGraGra().*/getLayoutPatternForTypeName(arc.getTypename());
final LayoutPattern lp = patterns.get(p);
// System.out.println("LayoutPatternsForTypeName
// "+lp.getEffectedEdgeType());
if (lp != null && lp.isEdgePattern()) {
if (lp.isXOffset()) {
if (lp.getOffset() > 0) {// also target x
// groesser als das von
// Source
if (!isFrozen(target))
txnew = Math.max(txnew, sxnew + 4);
else if (!isFrozen(source))
sxnew = Math.min(sxnew, txnew - 4);
} else {// also source x groesser als das von target
if (!isFrozen(source))
sxnew = Math.max(sxnew, txnew + 4);
else if (!isFrozen(target))
txnew = Math.min(txnew, sxnew - 4);
}
}// else
if (lp.isYOffset()) {
if (lp.getOffset() > 0) {// also target y
// groesser als source y
if (!isFrozen(target))
tynew = Math.max(tynew, synew + 4);
else if (!isFrozen(source))
synew = Math.min(synew, tynew - 4);
} else {// also source y groesser als target y
if (!isFrozen(source))
synew = Math.max(synew, tynew + 4);
else if (!isFrozen(target))
tynew = Math.min(tynew, synew - 4);
}
}
}
}
}
// //System.out.println("sourcex: "+sxnew+" sourcey: "+synew+"
// targetx: "+txnew+" targety: "+tynew);
// System.out.println("Layouter.layoutByArc:: isFrozen(source):
// "+isFrozen(source)+" isFrozen(target): "+isFrozen(target));
if (!(this.frozenPos && source.isFrozenByDefault()) && !isFrozen(source)) {
source.getAkt().setLocation(sxnew, synew);
source.getOpt().setLocation(source.getAkt());
}
if (!(this.frozenPos && target.isFrozenByDefault()) && !isFrozen(target)) {
target.getAkt().setLocation(txnew, tynew);
target.getOpt().setLocation(target.getAkt());
}
// aktuelle laengen neu berechnen
for (int k = 0; k < arcs.size(); k++) {
final EdArc a = arcs.get(k);
if (!a.getLArc().isFrozen())
a.getLArc().calcAktLength();
}
layoutDone = true;
}
// neue positionswerte aus den layoutnodes in die ednodes uebernehmen
eg.updateNodePosLtoE(nodes);
return layoutDone;
}
// combinedLayout1
public void combinedLayout(final EdGraph eg,
final List<EdNode> nodes,
final List<EdArc> arcs) {
combinedLayout(eg, nodes, arcs,
this.iters, this.iters,
this.edgeIntersctnIters);
}
// combinedLayout1
public void combinedLayout(final EdGraph eg,
final List<EdNode> nodes,
final List<EdArc> arcs,
final int itrs,
final int nodeit,
final int arcit) {
for (int i = 0; i < itrs; i++) {
layout(eg, nodes, arcs, nodeit);
layoutByArcLength(eg, nodes, arcs, arcit, 100);
}
}
// combinedLayout2 | default Layout
public boolean layoutGraph(final EdGraph eg,
final List<EdNode> nodes,
final List<EdArc> arcs) {
return layoutGraph(eg, nodes, arcs,
this.iters,
this.nodeIntersctnIters,
this.edgeIntersctnIters);
}
// combinedLayout2 | default Layout
public boolean layoutGraph(final EdGraph eg,
final List<EdNode> nodes,
final List<EdArc> arcs,
final int itrs,
final int nodeit,
final int arcit) {
// System.out.println("Layouter.layoutGraph... iters: "+iters+" nodeit: "+nodeit+" arcit: "+arcit);
for (int i = 0; i < arcs.size(); i++) {
final EdArc a = arcs.get(i);
if (!a.getLArc().isFrozen() && !this.frozenPos
&& !a.getLArc().isFrozenByDefault())
a.setAnchor(null);
}
final Vector<LayoutNode> lnodes = getLayoutNodes(nodes);
for (int i = 0; i < itrs; i++) {
final int temp2 = this.temperature;
for (int j = 0; j < nodeit; j++) {
calcNodeRepulse(lnodes);
calcDistToPos(eg.getArcs(), lnodes, temp2, eg.getGraphGen());
cool(temp2, j);
}
layoutByArcLength(eg, nodes, arcs, arcit, this.temperature);
cool(this.temperature, i);
}
this.overlapscnt = this.lmetric.getNodeIntersect(nodes, true);
if (/*!this.usepattern &&*/ this.overlapscnt == 0) {
eg.updateNodePosLtoE(nodes);
return false;
}
// jetzt nach metricverletzungen suchen und versuchen diese zu
// beheben.(momentan nur knotenueberschneidungen)
int x1, x2, y1, y2;
int ovlNodeIndx;
int stop = 100; //this.overlapscount;
while (this.overlapscnt > 0 && stop > 0) {
for (int i = 0; i < lnodes.size(); i++) {
final LayoutNode lnode1 = lnodes.get(i);
// System.out.println("this.usepattern: "+this.usepattern+" this.frozenPos:
// "+this.frozenPos+" lnode1.isFrozenAsDefault:
// "+lnode1.isFrozenAsDefault()+" isFrozen: "+isFrozen(lnode1));
if ((!this.usePattern && (lnode1.isFrozenByDefault() && this.frozenPos))
|| isFrozen(lnode1)) {// type pattern check
continue;
}
if (lnode1.isOverlapping()) {
ovlNodeIndx = this.lmetric.getOverlappingNode(lnodes, i);
if (ovlNodeIndx < 0) {
lnode1.unsetOverlap();
continue;
}
final LayoutNode lnode2 = lnodes.get(ovlNodeIndx);
if ((!this.usePattern && lnode2.isFrozenByDefault() && this.frozenPos)
|| isFrozen(lnode2)) {// type pattern check
continue;
}
// TODO spaeter vielleicht ne vernuenftige funktion zum
// verschieben ausdenken
if (lnode1.getAkt().x < lnode2.getAkt().x) {
x1 = lnode1.getAkt().x - lnode1.getEdNode().getWidth();
x2 = lnode2.getAkt().x + lnode2.getEdNode().getWidth();
} else {
x1 = lnode1.getAkt().x + lnode1.getEdNode().getWidth();
x2 = lnode2.getAkt().x - lnode2.getEdNode().getWidth();
}
if (lnode1.getAkt().y < lnode2.getAkt().y) {
y1 = lnode1.getAkt().y - lnode1.getEdNode().getHeight();
y2 = lnode2.getAkt().y + lnode2.getEdNode().getHeight();
} else {
y1 = lnode1.getAkt().y + lnode1.getEdNode().getHeight();
y2 = lnode2.getAkt().y - lnode2.getEdNode().getHeight();
}
// x1 = Math.max(x1,lnode1.getEdNode().getWidth());
// x2 = Math.max(x2,lnode2.getEdNode().getWidth());
// y1 = Math.max(y1,lnode1.getEdNode().getHeight());
// y2 = Math.max(y2,lnode2.getEdNode().getHeight());
// x1 =
// Math.min(x1,this.panel.width-lnode1.getEdNode().getWidth()*2);
// x2 =
// Math.min(x2,this.panel.width-lnode2.getEdNode().getWidth()*2);
// y1 =
// Math.min(y1,this.panel.height-lnode1.getEdNode().getHeight()*2);
// y2 =
// Math.min(y2,this.panel.height-lnode2.getEdNode().getHeight()*2);
// test
Point p1 = getRandomPosIfNeeded(x1, y1, lnode1);
Point p2 = getRandomPosIfNeeded(x2, y2, lnode2);
x1 = p1.x;
y1 = p1.y;
x2 = p2.x;
y2 = p2.y;
lnode1.setAkt(new Point(x1, y1));
lnode1.setOpt(lnode1.getAkt());
lnode2.setAkt(new Point(x2, y2));
lnode2.setOpt(lnode2.getAkt());
lnode1.unsetOverlap();
lnode2.unsetOverlap();
}
}
this.overlapscnt = this.lmetric.getNodeIntersect(nodes, true);
// System.out.println("Layouter.layoutGraph... this.overlapscount
// "+this.overlapscount);
stop--;
}
eg.updateNodePosLtoE(nodes);
return true;
}
/*
private boolean hasFreezingPattern(final Type t) {
boolean res = false;
final LayoutPattern lp = this.getLayoutPatternForType(t, "frozen_node");
if (lp != null) {
res = true;
}
return res;
}
*/
private boolean isFrozen(final LayoutNode ln) {
if (this.usePattern && this.layoutNode2Type != null) {
final Type t = this.layoutNode2Type.get(ln);
if (t != null) {
if (this.getLayoutPatternForType(t, "frozen_node") != null) {
return true;
}
return ln.isFrozen();
}
}
return ln.isFrozen();
}
// public void setFreezingForOldLayoutNode(boolean b){
//
// }
//
// public void setFreezingForOldLayoutEdge(boolean b){
//
// }
// public void setNodeTypeFrozen(Type nodetype, boolean frozen){
// if(!frozenNodeType.contains(nodetype) && frozen)
// frozenNodeType.add(nodetype);
// else if(frozenNodeType.contains(nodetype) && !frozen)
// frozenNodeType.remove(nodetype);
// }
public boolean graphContainsNewNodes(final EdGraph eg) {
final Vector<EdNode> nodes = eg.getNodes();
final Vector<EdNode> oldnodes = this.oldedgraph.getNodes();
for (int i = 0; i < nodes.size(); i++) {
final EdNode ni = nodes.get(i);
boolean found = false;
for (int j = 0; j < oldnodes.size(); j++) {
final EdNode nj = oldnodes.get(j);
if (ni.getBasisNode().compareTo(nj.getBasisNode())) {
found = true;
break;
}
}
if (!found)
return true;
}
return false;
}
private Vector<LayoutNode> getLayoutNodes(final List<EdNode> nodes) {
this.layoutNode2Type.clear();
final Vector<LayoutNode> ret = new Vector<LayoutNode>();
for (int i = 0; i < nodes.size(); i++) {
final EdNode n = nodes.get(i);
if (n != null && n.getLNode() != null) {
this.layoutNode2Type.put(n.getLNode(), n.getBasisNode().getType());
ret.addElement(n.getLNode());
}
}
return ret;
}
private Vector<LayoutArc> getLayoutArcs(final List<EdArc> arcs) {
final Vector<LayoutArc> ret = new Vector<LayoutArc>();
for (int i = 0; i < arcs.size(); i++) {
ret.addElement(arcs.get(i).getLArc());
}
return ret;
}
private Point getRandomPosIfNeeded(final int xpos, final int ypos, final LayoutNode lnode) {
// keine negativen werte bzw. keine werte so das der knoten aus dem bild
// verschwindet
int x = Math.max(xpos, lnode.getEdNode().getWidth());
// keine negativen werte
int y = Math.max(ypos, lnode.getEdNode().getHeight());
// keine werte die groesser sind als die panelbreite
// x = Math.min(x,this.panel.width-lnode.getEdNode().getWidth()*2);
// keine werte, die groesser als die Panelhoehe sind
// y = Math.min(y,this.panel.height-lnode.getEdNode().getHeight()*2);
// check minus and 0 Bereich
if (x <= 0 || (x - lnode.getEdNode().getWidth() < 0))
x = Math.max(x, lnode.getEdNode().getWidth());
if (y <= 0 || (y - lnode.getEdNode().getHeight() < 0))
y = Math.max(y, lnode.getEdNode().getHeight());
int nn = 0;
// keine werte die groesser sind als die panelbreite
while (x > (this.panel.width - lnode.getEdNode().getWidth()) && nn < 6) {
nn++;
// int r = this.random.nextInt(this.panel.width);
// x = x - Math.abs(r);
// bleib im + Bereich
// x = Math.abs(x - r);
x = Math.abs(x - Math.abs(this.random.nextInt(this.panel.width)));
}
nn = 0;
// keine werte, die groesser als die Panelhoehe sind
while (y > (this.panel.height - lnode.getEdNode().getHeight()) && nn < 6) {
nn++;
// int r = this.random.nextInt(this.panel.height);
// y = y - Math.abs(r);
// bleib im + Bereich
// y = Math.abs(y - r);
y = Math.abs(y - Math.abs(this.random.nextInt(this.panel.height)));
}
return new Point(x, y);
}
public void randomLayout(final EdGraph eg, final List<EdNode> nodes) {
// final int xdim = this.panel.width;
// final int ydim = this.panel.height;
final Vector<LayoutNode> lnodes = getLayoutNodes(nodes);
for (int i = 0; i < lnodes.size(); i++) {
final LayoutNode lnode = lnodes.get(i);
if ((!this.usePattern && (lnode.isFrozenByDefault() && this.frozenPos))
|| isFrozen(lnode)) {
continue;
}
int x = (Math.abs(this.random.nextInt(this.panel.width))); //%xdim;
int y = (Math.abs(this.random.nextInt(this.panel.height))); //%ydim;
lnode.setAkt(new Point(x, y));
lnode.setOpt(new Point(x, y));
}
eg.updateNodePosLtoE(nodes);
}
public void makeRandomLayoutOfNodes(final EdGraph eg, final List<EdNode> nodes) {
// System.out.println("Layouter.makeNodesRandomLayout:
// "+eg.getBasisGraph().getName());
final Vector<LayoutNode> lnodes = getLayoutNodes(nodes);
final int xdim = this.panel.width;
final int ydim = this.panel.height;
int x, y;
for (int i = 0; i < lnodes.size(); i++) {
final LayoutNode lnode = lnodes.get(i);
// System.out.println(i+". :: "+this.usepattern+"
// "+lnode.isFrozenByDefault()+" "+this.frozenPos+" "+lnode.isFrozen()+"
// "+isFrozen(lnode));
if ((!this.usePattern && (lnode.isFrozenByDefault() && this.frozenPos))
|| isFrozen(lnode)) {
continue;
}
if (lnode.getAge() == 0) {
final int rdx = Math.abs(this.random.nextInt(xdim));
// while(rdx < 50)
// rdx = Math.abs(this.random.nextInt(xdim));
final int rdy = Math.abs(this.random.nextInt(ydim));
// while(rdy < 50)
// rdy = Math.abs(this.random.nextInt(ydim));
x = rdx % xdim;
y = rdy % ydim;
if (x - lnode.getEdNode().getWidth() < 0)
x = Math.max(x, lnode.getEdNode().getWidth());
if (y - lnode.getEdNode().getHeight() < 0)
y = Math.max(y, lnode.getEdNode().getHeight());
// System.out.println("Layouter.makeRandomLayoutOfNodes::: node:
// "+lnode.getEdNode().getTypeName()+" dim: ["+xdim+" ,
// "+ydim+"] zufallszahl: "+rdx+" , "+rdy+" x: "+x+" y: "+y);
if (this.usePattern) {
final EdNode node = lnode.getEdNode();
final Vector<EdArc> arcs = eg.getArcs();
for (int j = 0; j < arcs.size(); j++) {
final EdArc arc = arcs.get(j);
if (arc.getSource().equals(node)
|| arc.getTarget().equals(node)) {
Vector<LayoutPattern> patterns = null;
if (arc.isElementOfTypeGraph())
patterns = getInheritancePattern(arc);
if (patterns == null)
patterns = getLayoutPatternsForType(arc
.getType().getBasisType());
for (int p = 0; p < patterns.size(); p++) {
final LayoutPattern lp = patterns.get(p);
if (lp != null && lp.isEdgePattern()) {
if (arc.getSource().equals(node)) {
if (lp.isXOffset()) {
x = arc.getTarget().getX()
- (lp.getOffset() * rdx % 200);
x = Math.max(x, node.getWidth());
x = Math.min(x, this.panel.width
- node.getWidth() * 2);
}// else
if (lp.isYOffset()) {
y = arc.getTarget().getY()
- (lp.getOffset() * rdy % 200);
y = Math.max(y, node.getHeight());
y = Math.max(y, this.panel.height
- node.getHeight() * 2);
}
// System.out.println("neue Source: x:
// "+x+" y: "+y+"\t Target: x:
// "+arc.getTarget().getX()+" y:
// "+arc.getTarget().getY());
} else { // node ist target
if (lp.isXOffset()) {
x = arc.getSource().getX()
+ (lp.getOffset() * rdx % 200);
x = Math.max(x, node.getWidth());
x = Math.min(x, this.panel.width
- node.getWidth() * 2);
}// else
if (lp.isYOffset()) {
y = arc.getSource().getY()
+ (lp.getOffset() * rdy % 200);
y = Math.max(y, node.getHeight());
y = Math.max(y, this.panel.height
- node.getHeight() * 2);
}
// System.out.println("Source: x:
// "+arc.getSource().getX()+" y:
// "+arc.getSource().getY()+"\t neues
// Target: x: "+x+" y: "+y);
}
}
}
}
}
}
lnode.setAkt(new Point(x, y));
lnode.setOpt(new Point(x, y));
// System.out.println("i: "+i+" dim: ["+xdim+" , "+ydim+"]
// zufallszahl: "+rdx+" , "+rdy+" x: "+x+" y: "+y);
}
}
eg.updateNodePosLtoE(nodes);
}
public void centreLayout(final EdGraph eg, final List<EdNode> nodes) {
// System.out.println("Layout.centerLayout ... ");
final Vector<LayoutNode> lnodes = getLayoutNodes(nodes);
int left = 0, right = 0, up = 0, down = 0;
int xmin = this.panel.width;
int xmax = 0;
int ymin = this.panel.height;
int ymax = 0;
for (int i = 0; i < lnodes.size(); i++) {
final LayoutNode lnode = lnodes.get(i);
if (lnode.getAkt().x < xmin) {
xmin = lnode.getAkt().x;
left = i;
} else if (lnode.getAkt().x > xmax) {
xmax = lnode.getAkt().x;
right = i;
}
if (lnode.getAkt().y < ymin) {
ymin = lnode.getAkt().y;
up = i;
} else if (lnode.getAkt().y < ymax) {
ymax = lnode.getAkt().y;
down = i;
}
}
final LayoutNode lnodeleft = lnodes.get(left);
final LayoutNode lnoderight = lnodes.get(right);
final LayoutNode lnodeup = lnodes.get(up);
final LayoutNode lnodedown = lnodes.get(down);
int center = this.panel.width / 2;
final int leftdif = center - lnodeleft.getAkt().x;
final int rightdif = lnoderight.getAkt().x - center;
center = this.panel.height / 2;
final int updif = center - lnodeup.getAkt().y;
final int downdif = lnodedown.getAkt().y - center;
final int x_change = (leftdif - rightdif) / 2;
final int y_change = (updif - downdif) / 2;
for (int i = 0; i < lnodes.size(); i++) {
final LayoutNode lnode = lnodes.get(i);
lnode.getAkt().x = lnode.getAkt().x + x_change;
lnode.getAkt().y = lnode.getAkt().y + y_change;
lnode.setOpt(new Point(lnode.getAkt()));
}
eg.updateNodePosLtoE(nodes);
}
public void setPanelSize(final Dimension dim) {
if (this.panelChangable || this.panel.width == 0 || this.panel.height == 0)
this.panel = dim;
}
public void allowChangePanelSize(final boolean b) {
this.panelChangable = b;
}
private Dimension getAverageNodeDim(final List<EdNode> nodes) {
float aw = 0, ah = 0;
if (!nodes.isEmpty()) {
for (int i = 0; i < nodes.size(); i++) {
EdNode e = nodes.get(i);
aw = aw + e.getWidth();
ah = ah + e.getHeight();
}
aw = aw / nodes.size();
ah = ah / nodes.size();
}
return new Dimension((int)aw, (int)ah);
}
public Dimension getNeededPanelSize(final List<EdNode> nodes) {
// average node size
final Dimension averagenodesize = getAverageNodeDim(nodes);
if (averagenodesize.width < 25 || averagenodesize.height < 25) {
averagenodesize.width = 25;
averagenodesize.height = 25;
}
final int ans = (averagenodesize.width >= averagenodesize.height) ? averagenodesize.width : averagenodesize.height;
int sizetmp = 2 * (int)Math.sqrt(nodes.size());
int sizeX = ans * sizetmp;
if (sizeX > 500 && sizeX < 1000)
sizeX = 1000;
int sizeY = sizeX*3/4;
final Dimension neededpanelsize = new Dimension(sizeX, sizeY);
// vergroessere zu kleine panel
if (neededpanelsize.width < 400 || neededpanelsize.height < 400) {
neededpanelsize.width = 400;
neededpanelsize.height = 400;
}
return neededpanelsize;
}
public void setOldEdGraph(final EdGraph eg) {
this.oldedgraph = eg;
}
public EdGraph getOldEdGraph() {
return this.oldedgraph;
}
/**
* momentan schrott, wegen fehlender vergleichbarkeit eines EdNodes mit
* seiner kopie koordiniert die blitzalterung von knoten deren nachbarn
* weggefallen sind
*
* @param eg
*/
public void shockAging(final EdGraph eg) { // blitzalterung
// System.out.println("Layouter.flashAging... graph gen.:
// "+eg.getGraphGen());
final Vector<EdNode> nodes = eg.getNodes();
final Vector<EdNode> oldnodes = this.oldedgraph.getNodes();
int index;
for (int i = 0; i < oldnodes.size(); i++) {
final EdNode oldnode = oldnodes.get(i);
if (oldnode.isInVectorByBasisNode(nodes) != -1) {
// also knoten wurde geloescht
// erst eingehende kanten...
final Vector<EdArc> arcsIn = this.oldedgraph.getIncomingArcs(oldnode);
for (int j = 0; j < arcsIn.size(); j++) {
final EdNode oldnode2 = (EdNode) arcsIn.get(j).getSource();
index = oldnode2.isInVectorByBasisNode(nodes);
if (index != -1) {// pruefen, ob der nachbarknoten nicht
// auch geloescht wurde
final EdNode node = nodes.get(index);
node.getLNode().setAge(
Math.max(oldnode.getLNode().getAge(), node
.getLNode().getAge()));
// System.out.println("flashAging: incom.arcs:: nodeID:
// "+node.getNodeID()+" age:
// "+node.getLNode().getAge());
}
}
// und fuer die ausgehenden
final Vector<EdArc> arcsOut = this.oldedgraph.getOutgoingArcs(oldnode);
for (int j = 0; j < arcsOut.size(); j++) {
final EdNode oldnode2 = (EdNode) arcsOut.get(j).getTarget();
index = oldnode2.isInVectorByBasisNode(nodes);
if (index != -1) {// pruefen, ob der nachbarknoten nicht
// auch geloescht wurde
// erstmal wird das alter auf den des geloeschten
// knotens gesetzt, die blitzalterung wird also nicht
// wieder zurueckgenommen.
// das wird spaeter vermutlich im alterungsprozess noch
// beruecksichtigt
final EdNode node = nodes.get(index);
node.getLNode().setAge(
Math.max(oldnode.getLNode().getAge(), node
.getLNode().getAge()));
// System.out.println("flashAging: outcom.arcs:: nodeID:
// "+node.getNodeID()+" age:
// "+node.getLNode().getAge());
}
}
}
}
}
public int getNodeIntersect(final List<EdNode> nodes, final boolean mark) {
return this.lmetric.getNodeIntersect(nodes, mark);
}
public void setGeneralEdgeLength(final int l) {
this.gnrlEdgeLngth = l;
}
public int getGeneralEdgeLength() {
return this.gnrlEdgeLngth;
}
public void setBeginTemperature(final int t) {
this.temperature = t;
}
public int getBeginTemperature() {
return this.temperature;
}
public void setIterationCount(final int count) {
this.iters = count;
}
public int getIterationCount() {
return this.iters;
}
public void setNodeIntersectionIterationCount(final int count) {
this.nodeIntersctnIters = count;
}
public void setEdgeIntersectionIterationCount(final int count) {
this.edgeIntersctnIters = count;
}
public boolean getJpgOutput() {
return this.jpgOutput;
}
public void setJpgOutput(final boolean b) {
this.jpgOutput = b;
}
public boolean usePattern() {
return this.usePattern;
}
public void setUsePattern(final boolean b) {
this.usePattern = b;
}
public void setFrozenByDefault(final boolean b) {
this.frozenPos = b;
}
public boolean isCentre() {
return this.centre;
}
public void setCentre(final boolean b) {
this.centre = b;
}
public boolean getWriteMetricValues() {
return this.writeMetrics;
}
public void setWriteMetricValues(final boolean b) {
this.writeMetrics = b;
}
public LayoutMetrics getLayoutMetrics() {
return this.lmetric;
}
/**
* erzeugt ein neues LayoutPattern mit den uebergebenen Parametern und fuegt
* es dem layoutPatterns-Vector von this hinzu.
*
* @param name
* name of layout pattern
* @param pType
* Patterntyp ("edge" oder "node") Vorerst nur "edge" sinnvoll
* @param type
* type des edges auf das sich dieses LayoutPattern bezieht
* @param offsetType
* in welche richtung soll das offset wirken ('x' oder 'y')
* @param offset
* gibt an, wie source und target einer edge zueinander liegen
* sollen. Bsp. offsettype='x' offset>0 target soll rechts von
* source liegen.
*/
public void createLayoutPattern(final String name, final String pType, final Type type,
final char offsetType, final int offset) {
final LayoutPattern lp = new LayoutPattern(name, pType, type, offsetType,
offset);
Vector<LayoutPattern> v = this.layoutPatterns.get(type);
if (v == null)
v = new Vector<LayoutPattern>();
v.add(lp);
this.layoutPatterns.put(type, v);
// System.out.println("Layouter.createLayoutPattern type: "+type+"
// count:"+v.size());
}
public void createLayoutPattern(final String name, final String pType, final Type type,
final int length) {
final LayoutPattern lp = new LayoutPattern(name, pType, type, length);
Vector<LayoutPattern> v = this.layoutPatterns.get(type);
if (v == null)
v = new Vector<LayoutPattern>();
v.add(lp);
this.layoutPatterns.put(type, v);
// System.out.println("Layouter.createLayoutPattern type: "+type+"
// count:"+v.size());
}
public void createLayoutPattern(final String name, final String pType, final Type type,
final boolean frozen) {
final LayoutPattern lp = new LayoutPattern(name, pType, type, frozen);
Vector<LayoutPattern> v = this.layoutPatterns.get(type);
if (v == null)
v = new Vector<LayoutPattern>();
v.add(lp);
this.layoutPatterns.put(type, v);
// System.out.println("Layouter.createLayoutPattern type:
// "+type.getName()+" count:"+v.size());
}
public void removeLayoutPattern(final Type type) {
if (this.layoutPatterns.contains(type)) {
this.layoutPatterns.remove(type);
}
}
public void removeLayoutPattern(final Type type, final String patternName) {
final Vector<LayoutPattern> v = this.layoutPatterns.get(type);
if (v == null || v.isEmpty())
return;
for (int i = 0; i < v.size(); i++) {
final LayoutPattern lp = v.get(i);
if (lp.getName().equals(patternName)) {
v.remove(lp);
i--;
}
}
this.layoutPatterns.put(type, v);
// System.out.println("Layouter.removeLayoutPattern type: "+typeName+"
// name: "+patternName+" count:"+v.size());
}
public Hashtable<Type, Vector<LayoutPattern>> getLayoutPatterns() {
return this.layoutPatterns;
}
public void clearLayoutPatterns() {
this.layoutPatterns.clear();
}
public Vector<LayoutPattern> getLayoutPatternsForType(final Type type) {
Vector<LayoutPattern> v = this.layoutPatterns.get(type);
if (v == null) {
v = new Vector<LayoutPattern>();
this.layoutPatterns.put(type, v);
}
return v;
}
public LayoutPattern getLayoutPatternForType(final Type type, final String patternName) {
final Vector<LayoutPattern> v = this.layoutPatterns.get(type);
if (v == null)
return null;
for (int i = 0; i < v.size(); i++) {
final LayoutPattern lp = v.get(i);
// System.out.println(lp+" "+lp.getName()+" "+patternName);
if (lp.getName().equals(patternName))
return lp;
}
return null;
}
public void setLayoutPatterns(final Hashtable<Type, Vector<LayoutPattern>> table) {
this.layoutPatterns.clear();
final Enumeration<Type> keys = table.keys();
while (keys.hasMoreElements()) {
final Type key = keys.nextElement();
this.layoutPatterns.put(key, table.get(key));
}
}
// private void delBendPoints(EdGraph eg){
// Vector arcs = eg.getArcs();
//
// EdArc arc;
//
// for (int i=0;i<arcs.size();i++){
// arc = (EdArc)arcs.get(i);
// arc.
// }
// }
}