1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-12-22 10:59:01 +00:00

Improve ELK support

This commit is contained in:
Arnaud Roques 2021-04-20 22:19:49 +02:00
parent bc1074a775
commit e1e6bcc5c8
30 changed files with 934 additions and 136 deletions

View File

@ -56,6 +56,7 @@ import net.sourceforge.plantuml.ugraphic.ImageBuilder;
public abstract class TitledDiagram extends AbstractPSystem implements Diagram, Annotated { public abstract class TitledDiagram extends AbstractPSystem implements Diagram, Annotated {
public static boolean FORCE_SMETANA = false; public static boolean FORCE_SMETANA = false;
public static boolean FORCE_ELK = false;
private DisplayPositionned title = DisplayPositionned.none(HorizontalAlignment.CENTER, VerticalAlignment.TOP); private DisplayPositionned title = DisplayPositionned.none(HorizontalAlignment.CENTER, VerticalAlignment.TOP);
@ -213,6 +214,8 @@ public abstract class TitledDiagram extends AbstractPSystem implements Diagram,
} }
public boolean isUseElk() { public boolean isUseElk() {
if (FORCE_ELK)
return true;
return this.useElk; return this.useElk;
} }

View File

@ -46,7 +46,7 @@ import java.util.Set;
import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.ILeaf;
import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.svek.Bibliotekon; import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.Line; import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UPolygon; import net.sourceforge.plantuml.ugraphic.UPolygon;
@ -68,7 +68,7 @@ public class Neighborhood {
public void drawU(UGraphic ug, double minX, double minY, Bibliotekon bibliotekon, Dimension2D shapeDim) { public void drawU(UGraphic ug, double minX, double minY, Bibliotekon bibliotekon, Dimension2D shapeDim) {
final Set<Point2D> contactPoints = new HashSet<Point2D>(); final Set<Point2D> contactPoints = new HashSet<Point2D>();
for (Link link : sametailLinks) { for (Link link : sametailLinks) {
final Line line = bibliotekon.getLine(link); final SvekLine line = bibliotekon.getLine(link);
final Point2D contact = line.getStartContactPoint(); final Point2D contact = line.getStartContactPoint();
contactPoints.add(contact); contactPoints.add(contact);
} }
@ -90,7 +90,7 @@ public class Neighborhood {
} }
for (Link link : allButSametails) { for (Link link : allButSametails) {
final Line line = bibliotekon.getLine(link); final SvekLine line = bibliotekon.getLine(link);
final Point2D contact = link.getEntity1() == leaf ? line.getStartContactPoint() : line.getEndContactPoint(); final Point2D contact = link.getEntity1() == leaf ? line.getStartContactPoint() : line.getEndContactPoint();
if (contact == null) { if (contact == null) {
assert false; assert false;

View File

@ -47,34 +47,61 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.eclipse.elk.core.RecursiveGraphLayoutEngine; import net.sourceforge.plantuml.AlignmentParam;
import org.eclipse.elk.core.options.CoreOptions;
import org.eclipse.elk.core.options.Direction;
import org.eclipse.elk.core.options.EdgeLabelPlacement;
import org.eclipse.elk.core.options.EdgeType;
import org.eclipse.elk.core.options.NodeLabelPlacement;
import org.eclipse.elk.core.options.SizeConstraint;
import org.eclipse.elk.core.options.SizeOptions;
import org.eclipse.elk.core.util.NullElkProgressMonitor;
import org.eclipse.elk.graph.ElkEdge;
import org.eclipse.elk.graph.ElkLabel;
import org.eclipse.elk.graph.ElkNode;
import org.eclipse.elk.graph.util.ElkGraphUtil;
import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.UseStyle;
import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram; import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.GroupType; import net.sourceforge.plantuml.cucadiagram.GroupType;
import net.sourceforge.plantuml.cucadiagram.IEntity;
import net.sourceforge.plantuml.cucadiagram.IGroup; import net.sourceforge.plantuml.cucadiagram.IGroup;
import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.ILeaf;
import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory; import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory;
/*
* You can choose between real "org.eclipse.elk..." classes or proxied "net.sourceforge.plantuml.elk.proxy..."
*
* Using proxied classes allows to compile PlantUML without having ELK available on the classpath.
* Since GraphViz is the default layout engine up to now, we do not want to enforce the use of ELK just for compilation.
* (for people not using maven)
*
* If you are debugging, you should probably switch to "org.eclipse.elk..." classes
*
*/
/*
import org.eclipse.elk.core.RecursiveGraphLayoutEngine;
import org.eclipse.elk.core.options.CoreOptions;
import org.eclipse.elk.core.options.Direction;
import org.eclipse.elk.core.options.EdgeLabelPlacement;
import org.eclipse.elk.core.options.HierarchyHandling;
import org.eclipse.elk.core.options.NodeLabelPlacement;
import org.eclipse.elk.core.util.NullElkProgressMonitor;
import org.eclipse.elk.graph.ElkEdge;
import org.eclipse.elk.graph.ElkLabel;
import org.eclipse.elk.graph.ElkNode;
import org.eclipse.elk.graph.util.ElkGraphUtil;
*/
import net.sourceforge.plantuml.elk.proxy.core.RecursiveGraphLayoutEngine;
import net.sourceforge.plantuml.elk.proxy.core.options.CoreOptions;
import net.sourceforge.plantuml.elk.proxy.core.options.Direction;
import net.sourceforge.plantuml.elk.proxy.core.options.EdgeLabelPlacement;
import net.sourceforge.plantuml.elk.proxy.core.options.HierarchyHandling;
import net.sourceforge.plantuml.elk.proxy.core.options.NodeLabelPlacement;
import net.sourceforge.plantuml.elk.proxy.core.util.NullElkProgressMonitor;
import net.sourceforge.plantuml.elk.proxy.graph.ElkEdge;
import net.sourceforge.plantuml.elk.proxy.graph.ElkLabel;
import net.sourceforge.plantuml.elk.proxy.graph.ElkNode;
import net.sourceforge.plantuml.elk.proxy.graph.util.ElkGraphUtil;
import net.sourceforge.plantuml.graphic.AbstractTextBlock; import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HorizontalAlignment;
@ -82,12 +109,19 @@ import net.sourceforge.plantuml.graphic.QuoteUtils;
import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.svek.Bibliotekon; import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.Cluster;
import net.sourceforge.plantuml.svek.ClusterDecoration;
import net.sourceforge.plantuml.svek.CucaDiagramFileMaker; import net.sourceforge.plantuml.svek.CucaDiagramFileMaker;
import net.sourceforge.plantuml.svek.DotStringFactory; import net.sourceforge.plantuml.svek.DotStringFactory;
import net.sourceforge.plantuml.svek.GeneralImageBuilder; import net.sourceforge.plantuml.svek.GeneralImageBuilder;
import net.sourceforge.plantuml.svek.GraphvizCrash; import net.sourceforge.plantuml.svek.GraphvizCrash;
import net.sourceforge.plantuml.svek.IEntityImage; import net.sourceforge.plantuml.svek.IEntityImage;
import net.sourceforge.plantuml.svek.PackageStyle;
import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.MinMax; import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -183,51 +217,114 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
} }
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
drawAllClusters(ug);
drawAllNodes(ug);
drawAllEdges(ug);
}
// Draw all clusters private void drawAllClusters(UGraphic ug) {
for (Entry<IGroup, ElkNode> ent : clusters.entrySet()) { for (Entry<IGroup, ElkNode> ent : clusters.entrySet()) {
final IGroup group = ent.getKey(); drawSingleCluster(ug, ent.getKey(), ent.getValue());
final ElkNode elkNode = ent.getValue();
final Point2D corner = getPosition(elkNode);
final URectangle rect = new URectangle(elkNode.getWidth(), elkNode.getHeight());
// Print a simple rectangle right now
ug.apply(HColorUtils.BLACK).apply(new UStroke(1.5)).apply(new UTranslate(corner)).draw(rect);
} }
}
// Draw all nodes private void drawAllNodes(UGraphic ug) {
for (Entry<ILeaf, ElkNode> ent : nodes.entrySet()) { for (Entry<ILeaf, ElkNode> ent : nodes.entrySet()) {
final ILeaf leaf = ent.getKey(); drawSingleNode(ug, ent.getKey(), ent.getValue());
final ElkNode elkNode = ent.getValue();
final IEntityImage image = printEntityInternal(leaf);
// Retrieve coord from ELK
final Point2D corner = getPosition(elkNode);
// Print the node image at right coord
image.drawU(ug.apply(new UTranslate(corner)));
} }
}
// Draw all edges private void drawAllEdges(UGraphic ug) {
for (Entry<Link, ElkEdge> ent : edges.entrySet()) { for (Entry<Link, ElkEdge> ent : edges.entrySet()) {
final Link link = ent.getKey(); final Link link = ent.getKey();
if (link.isInvis()) { if (link.isInvis()) {
continue; continue;
} }
final ElkEdge edge = ent.getValue(); drawSingleEdge(ug, link, ent.getValue());
}
}
// Unfortunately, we have to translate "edge" in its own "cluster" coordonate private void drawSingleCluster(UGraphic ug, IGroup group, ElkNode elkNode) {
final Point2D translate = getPosition(edge.getContainingNode()); final Point2D corner = getPosition(elkNode);
final UGraphic ugTranslated = ug.apply(new UTranslate(translate)); final URectangle rect = new URectangle(elkNode.getWidth(), elkNode.getHeight());
new ElkPath(link, edge, diagram, getLabel(link), getQualifier(link, 1), getQualifier(link, 2))
.drawU(ugTranslated);
PackageStyle packageStyle = group.getPackageStyle();
final ISkinParam skinParam = diagram.getSkinParam();
if (packageStyle == null) {
packageStyle = skinParam.packageStyle();
} }
final UmlDiagramType umlDiagramType = diagram.getUmlDiagramType();
final double shadowing;
final UStroke stroke;
if (UseStyle.useBetaStyle()) {
final Style style = Cluster.getDefaultStyleDefinition(umlDiagramType.getStyleName())
.getMergedStyle(skinParam.getCurrentStyleBuilder());
shadowing = style.value(PName.Shadowing).asDouble();
stroke = style.getStroke();
} else {
if (group.getUSymbol() == null) {
shadowing = skinParam.shadowing2(group.getStereotype(), USymbol.PACKAGE.getSkinParameter()) ? 3 : 0;
} else {
shadowing = skinParam.shadowing2(group.getStereotype(), group.getUSymbol().getSkinParameter()) ? 3
: 0;
}
stroke = Cluster.getStrokeInternal(group, skinParam);
}
HColor backColor = getBackColor(umlDiagramType);
backColor = Cluster.getBackColor(backColor, skinParam, group.getStereotype(),
umlDiagramType.getStyleName());
final double roundCorner = group.getUSymbol() == null ? 0
: group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, group.getStereotype());
final TextBlock ztitle = getTitleBlock(group);
final TextBlock zstereo = TextBlockUtils.empty(0, 0);
final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle,
zstereo, 0, 0, elkNode.getWidth(), elkNode.getHeight(), stroke);
final HColor borderColor = HColorUtils.BLACK;
decoration.drawU(ug.apply(new UTranslate(corner)), backColor, borderColor, shadowing, roundCorner,
skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false),
skinParam.getStereotypeAlignment());
// // Print a simple rectangle right now
// ug.apply(HColorUtils.BLACK).apply(new UStroke(1.5)).apply(new UTranslate(corner)).draw(rect);
}
private TextBlock getTitleBlock(IGroup g) {
final Display label = g.getDisplay();
if (label == null) {
return TextBlockUtils.empty(0, 0);
}
final ISkinParam skinParam = diagram.getSkinParam();
final FontConfiguration fontConfiguration = g.getFontConfigurationForTitle(skinParam);
return label.create(fontConfiguration, HorizontalAlignment.CENTER, skinParam);
}
private HColor getBackColor(UmlDiagramType umlDiagramType) {
return null;
}
private void drawSingleNode(UGraphic ug, ILeaf leaf, ElkNode elkNode) {
final IEntityImage image = printEntityInternal(leaf);
// Retrieve coord from ELK
final Point2D corner = getPosition(elkNode);
// Print the node image at right coord
image.drawU(ug.apply(new UTranslate(corner)));
}
private void drawSingleEdge(UGraphic ug, Link link, ElkEdge edge) {
// Unfortunately, we have to translate "edge" in its own "cluster" coordinate
final Point2D translate = getPosition(edge.getContainingNode());
final ElkPath elkPath = new ElkPath(diagram, SName.classDiagram, link, edge, getLabel(link),
getQualifier(link, 1), getQualifier(link, 2));
elkPath.drawU(ug.apply(new UTranslate(translate)));
} }
public Dimension2D calculateDimension(StringBounder stringBounder) { public Dimension2D calculateDimension(StringBounder stringBounder) {
@ -253,6 +350,14 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
return result; return result;
} }
private ElkNode getElkNode(final IEntity entity) {
ElkNode node = nodes.get(entity);
if (node == null) {
node = clusters.get(entity);
}
return node;
}
@Override @Override
public ImageData createFile(OutputStream os, List<String> dotStrings, FileFormatOption fileFormatOption) public ImageData createFile(OutputStream os, List<String> dotStrings, FileFormatOption fileFormatOption)
throws IOException { throws IOException {
@ -261,6 +366,7 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
try { try {
final ElkNode root = ElkGraphUtil.createGraph(); final ElkNode root = ElkGraphUtil.createGraph();
root.setProperty(CoreOptions.DIRECTION, Direction.DOWN); root.setProperty(CoreOptions.DIRECTION, Direction.DOWN);
root.setProperty(CoreOptions.HIERARCHY_HANDLING, HierarchyHandling.INCLUDE_CHILDREN);
printAllSubgroups(root, diagram.getRootGroup()); printAllSubgroups(root, diagram.getRootGroup());
printEntities(root, getUnpackagedEntities()); printEntities(root, getUnpackagedEntities());
@ -360,20 +466,26 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
// No idea of what we are doing here :-) // No idea of what we are doing here :-)
label.setProperty(CoreOptions.NODE_LABELS_PLACEMENT, label.setProperty(CoreOptions.NODE_LABELS_PLACEMENT,
EnumSet.of(NodeLabelPlacement.INSIDE, NodeLabelPlacement.H_CENTER, NodeLabelPlacement.V_CENTER)); EnumSet.of(NodeLabelPlacement.INSIDE, NodeLabelPlacement.H_CENTER, NodeLabelPlacement.V_CENTER));
// This padding setting have no impact ? // This padding setting have no impact ?
// label.setProperty(CoreOptions.NODE_LABELS_PADDING, new ElkPadding(100.0)); // label.setProperty(CoreOptions.NODE_LABELS_PADDING, new ElkPadding(100.0));
node.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, EnumSet.of(SizeConstraint.NODE_LABELS));
node.setProperty(CoreOptions.NODE_SIZE_OPTIONS, EnumSet.noneOf(SizeOptions.class)); // final EnumSet<SizeConstraint> constraints =
// EnumSet.of(SizeConstraint.NODE_LABELS);
// node.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, constraints);
// node.setProperty(CoreOptions.NODE_SIZE_OPTIONS,
// EnumSet.noneOf(SizeOptions.class));
// Let's store this // Let's store this
nodes.put(leaf, node); nodes.put(leaf, node);
} }
private void manageSingleEdge(final Link link) { private void manageSingleEdge(final Link link) {
final ElkNode node1 = nodes.get(link.getEntity1()); final ElkNode node1 = getElkNode(link.getEntity1());
final ElkNode node2 = nodes.get(link.getEntity2()); final ElkNode node2 = getElkNode(link.getEntity2());
final ElkEdge edge = ElkGraphUtil.createEdge(node1.getParent()); final ElkEdge edge = ElkGraphUtil.createSimpleEdge(node1, node2);
final TextBlock labelLink = getLabel(link); final TextBlock labelLink = getLabel(link);
if (labelLink != null) { if (labelLink != null) {
@ -383,7 +495,7 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
edgeLabel.setDimensions(dim.getWidth(), dim.getHeight()); edgeLabel.setDimensions(dim.getWidth(), dim.getHeight());
// Duplicated, with qualifier, but who cares? // Duplicated, with qualifier, but who cares?
edge.setProperty(CoreOptions.EDGE_LABELS_INLINE, true); edge.setProperty(CoreOptions.EDGE_LABELS_INLINE, true);
edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION); // edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION);
} }
if (link.getQualifier1() != null) { if (link.getQualifier1() != null) {
final ElkLabel edgeLabel = ElkGraphUtil.createLabel(edge); final ElkLabel edgeLabel = ElkGraphUtil.createLabel(edge);
@ -394,7 +506,7 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
edgeLabel.setProperty(CoreOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.TAIL); edgeLabel.setProperty(CoreOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.TAIL);
// Duplicated, with main label, but who cares? // Duplicated, with main label, but who cares?
edge.setProperty(CoreOptions.EDGE_LABELS_INLINE, true); edge.setProperty(CoreOptions.EDGE_LABELS_INLINE, true);
edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION); // edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION);
} }
if (link.getQualifier2() != null) { if (link.getQualifier2() != null) {
final ElkLabel edgeLabel = ElkGraphUtil.createLabel(edge); final ElkLabel edgeLabel = ElkGraphUtil.createLabel(edge);
@ -405,10 +517,9 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
edgeLabel.setProperty(CoreOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.HEAD); edgeLabel.setProperty(CoreOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.HEAD);
// Duplicated, with main label, but who cares? // Duplicated, with main label, but who cares?
edge.setProperty(CoreOptions.EDGE_LABELS_INLINE, true); edge.setProperty(CoreOptions.EDGE_LABELS_INLINE, true);
edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION); // edge.setProperty(CoreOptions.EDGE_TYPE, EdgeType.ASSOCIATION);
} }
edge.getSources().add(node1);
edge.getTargets().add(node2);
edges.put(link, edge); edges.put(link, edge);
} }

View File

@ -35,27 +35,53 @@
*/ */
package net.sourceforge.plantuml.elk; package net.sourceforge.plantuml.elk;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.List;
/*
* You can choose between real "org.eclipse.elk..." classes or proxied "net.sourceforge.plantuml.elk.proxy..."
*
* Using proxied classes allows to compile PlantUML without having ELK available on the classpath.
* Since GraphViz is the default layout engine up to now, we do not want to enforce the use of ELK just for compilation.
* (for people not using maven)
*
* If you are debugging, you should probably switch to "org.eclipse.elk..." classes
*
*/
/*
import org.eclipse.elk.graph.ElkBendPoint; import org.eclipse.elk.graph.ElkBendPoint;
import org.eclipse.elk.graph.ElkEdge; import org.eclipse.elk.graph.ElkEdge;
import org.eclipse.elk.graph.ElkEdgeSection; import org.eclipse.elk.graph.ElkEdgeSection;
import org.eclipse.elk.graph.ElkLabel; import org.eclipse.elk.graph.ElkLabel;
import org.eclipse.emf.common.util.EList; */
import net.sourceforge.plantuml.elk.proxy.graph.ElkBendPoint;
import net.sourceforge.plantuml.elk.proxy.graph.ElkEdge;
import net.sourceforge.plantuml.elk.proxy.graph.ElkEdgeSection;
import net.sourceforge.plantuml.elk.proxy.graph.ElkLabel;
import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.LineParam; import net.sourceforge.plantuml.LineParam;
import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram; import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.LinkDecor;
import net.sourceforge.plantuml.cucadiagram.LinkType; import net.sourceforge.plantuml.cucadiagram.LinkType;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.graphic.color.ColorType; import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.skin.rose.Rose;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactory;
import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryExtends;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class ElkPath implements UDrawable { public class ElkPath implements UDrawable {
@ -67,9 +93,10 @@ public class ElkPath implements UDrawable {
private final TextBlock headLabel; private final TextBlock headLabel;
private final TextBlock tailLabel; private final TextBlock tailLabel;
private final Rose rose = new Rose(); private final Rose rose = new Rose();
private final SName styleName;
public ElkPath(Link link, ElkEdge edge, CucaDiagram diagram, TextBlock centerLabel, TextBlock tailLabel, public ElkPath(CucaDiagram diagram, SName styleName, Link link, ElkEdge edge, TextBlock centerLabel,
TextBlock headLabel) { TextBlock tailLabel, TextBlock headLabel) {
this.link = link; this.link = link;
this.edge = edge; this.edge = edge;
@ -77,6 +104,8 @@ public class ElkPath implements UDrawable {
this.centerLabel = centerLabel; this.centerLabel = centerLabel;
this.tailLabel = tailLabel; this.tailLabel = tailLabel;
this.headLabel = headLabel; this.headLabel = headLabel;
this.styleName = styleName;
} }
private ColorParam getArrowColorParam() { private ColorParam getArrowColorParam() {
@ -119,18 +148,46 @@ public class ElkPath implements UDrawable {
} }
ug = ug.apply(stroke).apply(color); ug = ug.apply(stroke).apply(color);
final EList<ElkEdgeSection> sections = edge.getSections(); final List<ElkEdgeSection> sections = edge.getSections();
if (sections.size() == 0) { if (sections.size() == 0) {
System.err.println("Strange: no section?"); System.err.println("Strange: no section?");
System.err.println("Maybe a 'Long hierarchical edge' " + edge.isHierarchical()); System.err.println("Maybe a 'Long hierarchical edge' " + edge.isHierarchical());
return;
} else { } else {
drawSections(ug, sections); drawSections(ug, sections);
} }
final UDrawable extremityFactory1 = getDecors(link.getType().getDecor1(), Math.PI / 2, HColorUtils.WHITE);
final UDrawable extremityFactory2 = getDecors(link.getType().getDecor2(), -Math.PI / 2, HColorUtils.WHITE);
if (extremityFactory1 != null) {
final double x = sections.get(0).getEndX();
final double y = sections.get(0).getEndY();
extremityFactory1.drawU(ug.apply(new UTranslate(x, y)));
}
if (extremityFactory2 != null) {
final double x = sections.get(0).getStartX();
final double y = sections.get(0).getStartY();
extremityFactory2.drawU(ug.apply(new UTranslate(x, y)));
}
drawLabels(ug); drawLabels(ug);
} }
private UDrawable getDecors(LinkDecor decors, double angle, HColor backColor) {
// For legacy reason, extends are treated differently
if (decors == LinkDecor.EXTENDS) {
return new ExtremityFactoryExtends(backColor).createUDrawable(new Point2D.Double(), angle, null);
}
final ExtremityFactory extremityFactory = decors.getExtremityFactory(backColor);
if (extremityFactory == null) {
return null;
}
return extremityFactory.createUDrawable(new Point2D.Double(), angle, null);
}
private void drawLabels(UGraphic ug) { private void drawLabels(UGraphic ug) {
for (ElkLabel label : edge.getLabels()) { for (ElkLabel label : edge.getLabels()) {
final double x = label.getX(); final double x = label.getX();
@ -151,9 +208,9 @@ public class ElkPath implements UDrawable {
} }
} }
private void drawSections(UGraphic ug, final EList<ElkEdgeSection> sections) { private void drawSections(UGraphic ug, final Collection<ElkEdgeSection> sections) {
for (ElkEdgeSection section : sections) { for (ElkEdgeSection section : sections) {
final EList<ElkBendPoint> points = section.getBendPoints(); final Collection<ElkBendPoint> points = section.getBendPoints();
double x1 = section.getStartX(); double x1 = section.getStartX();
double y1 = section.getStartY(); double y1 = section.getStartY();

View File

@ -0,0 +1,7 @@
package net.sourceforge.plantuml.elk.proxy;
public interface EnumProxy {
public Enum getTrueObject();
}

View File

@ -0,0 +1,227 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.elk.proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/*
* Various methods to do Java introspection
*/
public class Reflect {
public static Class clazz(String className) {
try {
return Class.forName(className);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Enum getEnum(String clazz, String name) {
try {
final Class cl = clazz(clazz);
for (Object en : cl.getEnumConstants()) {
if (en.toString().equals(name)) {
return (Enum) en;
}
}
throw new UnsupportedOperationException(name);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object opt(String className, String fieldname) {
try {
final Class<?> cl = Class.forName(className);
final Field field = cl.getField(fieldname);
return field.get(null);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object newInstance(String className) {
try {
final Class<?> cl = Class.forName(className);
return cl.newInstance();
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object newInstance(String className, Object arg1) {
try {
final Class<?> cl = Class.forName(className);
final Constructor<?> m = cl.getConstructor(arg1.getClass());
return m.newInstance(arg1);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object field(String className, String fieldName) {
try {
final Class<?> cl = Class.forName(className);
final Field f = cl.getField(fieldName);
return f.get(null);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic(String className, String method) {
try {
final Class<?> cl = Class.forName(className);
final Method m = cl.getMethod(method);
return m.invoke(null);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic(String className, String method, Object arg1) {
try {
final Class<?> cl = Class.forName(className);
final Method m = cl.getMethod(method, arg1.getClass());
return m.invoke(null, arg1);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic(String className, String method, Object arg1, Object arg2) {
try {
final Class<?> cl = Class.forName(className);
final Method m = cl.getMethod(method, arg1.getClass(), arg2.getClass());
return m.invoke(null, arg1, arg2);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic2(String className, String method, Object arg1) {
try {
final Class<?> cl = Class.forName(className);
final Method m = getStaticMethod(cl, method, 1);
return m.invoke(null, arg1);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object callStatic2(String className, String method, Object arg1, Object arg2) {
try {
final Class<?> cl = Class.forName(className);
final Method m = getStaticMethod(cl, method, 2);
return m.invoke(null, arg1, arg2);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Method getStaticMethod(Class<?> cl, String method, int nbArgs) {
for (Method m : cl.getMethods()) {
if (m.getName().equals(method) && m.getParameters().length == nbArgs) {
return m;
}
}
throw new IllegalArgumentException();
}
public static Object call(Object instance, String method) {
try {
final Method m = instance.getClass().getMethod(method);
return m.invoke(instance);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object call(Object instance, String method, Object arg1) {
try {
final Method m = instance.getClass().getMethod(method, arg1.getClass());
return m.invoke(instance, arg1);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object call(Object instance, String method, Object arg1, Object arg2) {
try {
final Method m = instance.getClass().getMethod(method, arg1.getClass(), arg2.getClass());
return m.invoke(instance, arg1, arg2);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Object call2(Object instance, String method, Object arg1, Object arg2) {
try {
final Method m = getMethod(instance, method, 2);
return m.invoke(instance, arg1, arg2);
} catch (Throwable t) {
t.printStackTrace();
throw new IllegalArgumentException(t);
}
}
public static Method getMethod(Object instance, String method, int nbArgs) {
for (Method m : instance.getClass().getMethods()) {
if (m.getName().equals(method) && m.getParameters().length == nbArgs) {
return m;
}
}
throw new IllegalArgumentException();
}
}

View File

@ -0,0 +1,15 @@
package net.sourceforge.plantuml.elk.proxy.core;
import net.sourceforge.plantuml.elk.proxy.Reflect;
import net.sourceforge.plantuml.elk.proxy.core.util.NullElkProgressMonitor;
import net.sourceforge.plantuml.elk.proxy.graph.ElkNode;
public class RecursiveGraphLayoutEngine {
private final Object obj = Reflect.newInstance("org.eclipse.elk.core.RecursiveGraphLayoutEngine");
public void layout(ElkNode root, NullElkProgressMonitor monitor) {
Reflect.call2(obj, "layout", root.obj, monitor.obj);
}
}

View File

@ -0,0 +1,16 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class CoreOptions {
public static final Object DIRECTION = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "DIRECTION");
public static final Object EDGE_LABELS_INLINE = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "EDGE_LABELS_INLINE");
public static final Object NODE_SIZE_CONSTRAINTS = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "NODE_SIZE_CONSTRAINTS");
public static final Object HIERARCHY_HANDLING = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "HIERARCHY_HANDLING");
public static final Object EDGE_LABELS_PLACEMENT = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "EDGE_LABELS_PLACEMENT");
public static final Object EDGE_TYPE = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "EDGE_TYPE");
public static final Object NODE_LABELS_PLACEMENT = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "NODE_LABELS_PLACEMENT");
public static final Object NODE_SIZE_OPTIONS = Reflect.field("org.eclipse.elk.core.options.CoreOptions", "NODE_SIZE_OPTIONS");
}

View File

@ -0,0 +1,9 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class Direction {
public static final Object DOWN = Reflect.field("org.eclipse.elk.core.options.Direction", "DOWN");
}

View File

@ -0,0 +1,15 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.EnumProxy;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public enum EdgeLabelPlacement implements EnumProxy {
TAIL, HEAD;
@Override
public Enum getTrueObject() {
return Reflect.getEnum("org.eclipse.elk.core.options.EdgeLabelPlacement", name());
}
}

View File

@ -0,0 +1,9 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class HierarchyHandling {
public static final Object INCLUDE_CHILDREN = Reflect.field("org.eclipse.elk.core.options.HierarchyHandling", "INCLUDE_CHILDREN");
}

View File

@ -0,0 +1,15 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.EnumProxy;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public enum NodeLabelPlacement implements EnumProxy {
INSIDE, V_CENTER, H_CENTER;
@Override
public Enum getTrueObject() {
return Reflect.getEnum("org.eclipse.elk.core.options.NodeLabelPlacement", name());
}
}

View File

@ -0,0 +1,15 @@
package net.sourceforge.plantuml.elk.proxy.core.options;
import net.sourceforge.plantuml.elk.proxy.EnumProxy;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public enum SizeConstraint implements EnumProxy {
NODE_LABELS;
@Override
public Enum getTrueObject() {
return Reflect.getEnum("org.eclipse.elk.core.options.SizeConstraint", name());
}
}

View File

@ -0,0 +1,10 @@
package net.sourceforge.plantuml.elk.proxy.core.util;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class NullElkProgressMonitor {
public final Object obj = Reflect.newInstance("org.eclipse.elk.core.util.NullElkProgressMonitor");
}

View File

@ -0,0 +1,34 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkBendPoint {
public final Object obj;
public ElkBendPoint(Object obj) {
if (obj == null) {
throw new IllegalArgumentException();
}
this.obj = obj;
}
@Override
public int hashCode() {
return this.obj.hashCode();
}
@Override
public boolean equals(Object other) {
return this.obj.equals(((ElkBendPoint) other).obj);
}
public double getX() {
return (Double) Reflect.call(obj, "getX");
}
public double getY() {
return (Double) Reflect.call(obj, "getY");
}
}

View File

@ -0,0 +1,41 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkEdge extends ElkWithProperty {
public ElkEdge(Object obj) {
super(obj);
}
public ElkNode getContainingNode() {
return new ElkNode(Reflect.call(obj, "getContainingNode"));
}
public Collection<ElkLabel> getLabels() {
final List<ElkLabel> result = new ArrayList<ElkLabel>();
Collection internal = (Collection) Reflect.call(obj, "getLabels");
for (Object element : internal) {
result.add(new ElkLabel(element));
}
return result;
}
public List<ElkEdgeSection> getSections() {
final List<ElkEdgeSection> result = new ArrayList<ElkEdgeSection>();
Collection internal = (Collection) Reflect.call(obj, "getSections");
for (Object element : internal) {
result.add(new ElkEdgeSection(element));
}
return result;
}
public boolean isHierarchical() {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,55 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkEdgeSection {
public final Object obj;
public ElkEdgeSection(Object obj) {
if (obj == null) {
throw new IllegalArgumentException();
}
this.obj = obj;
}
@Override
public int hashCode() {
return this.obj.hashCode();
}
@Override
public boolean equals(Object other) {
return this.obj.equals(((ElkEdgeSection) other).obj);
}
public double getStartX() {
return (Double) Reflect.call(obj, "getStartX");
}
public double getStartY() {
return (Double) Reflect.call(obj, "getStartY");
}
public double getEndX() {
return (Double) Reflect.call(obj, "getEndX");
}
public double getEndY() {
return (Double) Reflect.call(obj, "getEndY");
}
public Collection<ElkBendPoint> getBendPoints() {
final List<ElkBendPoint> result = new ArrayList<ElkBendPoint>();
Collection internal = (Collection) Reflect.call(obj, "getBendPoints");
for (Object element : internal) {
result.add(new ElkBendPoint(element));
}
return result;
}
}

View File

@ -0,0 +1,31 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkLabel extends ElkWithProperty {
public ElkLabel(Object obj) {
super(obj);
}
public void setText(String text) {
Reflect.call(obj, "setText", text);
}
public void setDimensions(double width, double height) {
Reflect.call2(obj, "setDimensions", width, height);
}
public String getText() {
return (String) Reflect.call(obj, "getText");
}
public double getX() {
return (Double) Reflect.call(obj, "getX");
}
public double getY() {
return (Double) Reflect.call(obj, "getY");
}
}

View File

@ -0,0 +1,51 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import java.util.ArrayList;
import java.util.Collection;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkNode extends ElkWithProperty {
public ElkNode(Object obj) {
super(obj);
}
public ElkNode getParent() {
final Object tmp = Reflect.call(obj, "getParent");
if (tmp == null) {
return null;
}
return new ElkNode(tmp);
}
public double getX() {
return (Double) Reflect.call(obj, "getX");
}
public double getY() {
return (Double) Reflect.call(obj, "getY");
}
public Collection<ElkLabel> getLabels() {
final Collection<ElkLabel> result = new ArrayList<ElkLabel>();
final Collection internal = (Collection) Reflect.call(obj, "getLabels");
for (Object element : internal) {
result.add(new ElkLabel(element));
}
return result;
}
public double getWidth() {
return (Double) Reflect.call(obj, "getWidth");
}
public double getHeight() {
return (Double) Reflect.call(obj, "getHeight");
}
public void setDimensions(double width, double height) {
Reflect.call2(obj, "setDimensions", width, height);
}
}

View File

@ -0,0 +1,49 @@
package net.sourceforge.plantuml.elk.proxy.graph;
import java.util.Collection;
import java.util.EnumSet;
import net.sourceforge.plantuml.elk.proxy.EnumProxy;
import net.sourceforge.plantuml.elk.proxy.Reflect;
public class ElkWithProperty {
public final Object obj;
public ElkWithProperty(Object obj) {
if (obj == null) {
throw new IllegalArgumentException();
}
this.obj = obj;
}
@Override
final public int hashCode() {
return this.obj.hashCode();
}
@Override
final public boolean equals(Object other) {
return this.obj.equals(((ElkWithProperty) other).obj);
}
final public void setProperty(Object key, Object value) {
if (value instanceof EnumSet) {
EnumSet result = null;
for (Object foo : (Collection) value) {
final EnumProxy elk = (EnumProxy) foo;
if (result == null) {
result = EnumSet.noneOf((Class<Enum>) elk.getClass());
}
result.add(elk);
}
Reflect.call2(obj, "setProperty", key, result);
} else if (value instanceof EnumProxy) {
final Enum elk = ((EnumProxy) value).getTrueObject();
Reflect.call2(obj, "setProperty", key, elk);
} else {
Reflect.call2(obj, "setProperty", key, value);
}
}
}

View File

@ -0,0 +1,31 @@
package net.sourceforge.plantuml.elk.proxy.graph.util;
import net.sourceforge.plantuml.elk.proxy.Reflect;
import net.sourceforge.plantuml.elk.proxy.graph.ElkEdge;
import net.sourceforge.plantuml.elk.proxy.graph.ElkLabel;
import net.sourceforge.plantuml.elk.proxy.graph.ElkNode;
public class ElkGraphUtil {
public static ElkLabel createLabel(ElkEdge edge) {
return new ElkLabel(Reflect.callStatic2("org.eclipse.elk.graph.util.ElkGraphUtil", "createLabel", edge.obj));
}
public static ElkLabel createLabel(ElkNode node) {
return new ElkLabel(Reflect.callStatic2("org.eclipse.elk.graph.util.ElkGraphUtil", "createLabel", node.obj));
}
public static ElkNode createNode(ElkNode root) {
return new ElkNode(Reflect.callStatic2("org.eclipse.elk.graph.util.ElkGraphUtil", "createNode", root.obj));
}
public static ElkEdge createSimpleEdge(ElkNode node1, ElkNode node2) {
return new ElkEdge(Reflect.callStatic2("org.eclipse.elk.graph.util.ElkGraphUtil", "createSimpleEdge", node1.obj,
node2.obj));
}
public static ElkNode createGraph() {
return new ElkNode(Reflect.callStatic("org.eclipse.elk.graph.util.ElkGraphUtil", "createGraph"));
}
}

View File

@ -55,9 +55,9 @@ public class Bibliotekon {
private final Map<ILeaf, SvekNode> nodeMap = new LinkedHashMap<ILeaf, SvekNode>();; private final Map<ILeaf, SvekNode> nodeMap = new LinkedHashMap<ILeaf, SvekNode>();;
private final List<Line> lines0 = new ArrayList<Line>(); private final List<SvekLine> lines0 = new ArrayList<SvekLine>();
private final List<Line> lines1 = new ArrayList<Line>(); private final List<SvekLine> lines1 = new ArrayList<SvekLine>();
private final List<Line> allLines = new ArrayList<Line>(); private final List<SvekLine> allLines = new ArrayList<SvekLine>();
public SvekNode createNode(ILeaf ent, IEntityImage image, ColorSequence colorSequence, StringBounder stringBounder) { public SvekNode createNode(ILeaf ent, IEntityImage image, ColorSequence colorSequence, StringBounder stringBounder) {
final SvekNode node = new SvekNode(ent, image, colorSequence, stringBounder); final SvekNode node = new SvekNode(ent, image, colorSequence, stringBounder);
@ -74,13 +74,13 @@ public class Bibliotekon {
return null; return null;
} }
public void addLine(Line line) { public void addLine(SvekLine line) {
allLines.add(line); allLines.add(line);
if (first(line)) { if (first(line)) {
if (line.hasNoteLabelText()) { if (line.hasNoteLabelText()) {
// lines0.add(0, line); // lines0.add(0, line);
for (int i = 0; i < lines0.size(); i++) { for (int i = 0; i < lines0.size(); i++) {
final Line other = lines0.get(i); final SvekLine other = lines0.get(i);
if (other.hasNoteLabelText() == false && line.sameConnections(other)) { if (other.hasNoteLabelText() == false && line.sameConnections(other)) {
lines0.add(i, line); lines0.add(i, line);
return; return;
@ -95,7 +95,7 @@ public class Bibliotekon {
} }
} }
private static boolean first(Line line) { private static boolean first(SvekLine line) {
final int length = line.getLength(); final int length = line.getLength();
if (length == 1) { if (length == 1) {
return true; return true;
@ -158,15 +158,15 @@ public class Bibliotekon {
return Collections.unmodifiableMap(result); return Collections.unmodifiableMap(result);
} }
public List<Line> allLines() { public List<SvekLine> allLines() {
return Collections.unmodifiableList(allLines); return Collections.unmodifiableList(allLines);
} }
public List<Line> lines0() { public List<SvekLine> lines0() {
return Collections.unmodifiableList(lines0); return Collections.unmodifiableList(lines0);
} }
public List<Line> lines1() { public List<SvekLine> lines1() {
return Collections.unmodifiableList(lines1); return Collections.unmodifiableList(lines1);
} }
@ -178,9 +178,9 @@ public class Bibliotekon {
return Collections.unmodifiableCollection(nodeMap.values()); return Collections.unmodifiableCollection(nodeMap.values());
} }
public List<Line> getAllLineConnectedTo(IEntity leaf) { public List<SvekLine> getAllLineConnectedTo(IEntity leaf) {
final List<Line> result = new ArrayList<Line>(); final List<SvekLine> result = new ArrayList<SvekLine>();
for (Line line : allLines) { for (SvekLine line : allLines) {
if (line.isLinkFromOrTo(leaf)) { if (line.isLinkFromOrTo(leaf)) {
result.add(line); result.add(line);
} }
@ -188,8 +188,8 @@ public class Bibliotekon {
return Collections.unmodifiableList(result); return Collections.unmodifiableList(result);
} }
public Line getLine(Link link) { public SvekLine getLine(Link link) {
for (Line line : allLines) { for (SvekLine line : allLines) {
if (line.isLink(link)) { if (line.isLink(link)) {
return line; return line;
} }
@ -198,7 +198,7 @@ public class Bibliotekon {
} }
public IEntity getOnlyOther(IEntity entity) { public IEntity getOnlyOther(IEntity entity) {
for (Line line : allLines) { for (SvekLine line : allLines) {
final IEntity other = line.getOther(entity); final IEntity other = line.getOther(entity);
if (other != null) { if (other != null) {
return other; return other;

View File

@ -178,7 +178,7 @@ public class Cluster implements Moveable {
return Collections.unmodifiableList(nodes); return Collections.unmodifiableList(nodes);
} }
private List<SvekNode> getNodesOrderedTop(Collection<Line> lines) { private List<SvekNode> getNodesOrderedTop(Collection<SvekLine> lines) {
final List<SvekNode> firsts = new ArrayList<SvekNode>(); final List<SvekNode> firsts = new ArrayList<SvekNode>();
final Set<String> tops = new HashSet<String>(); final Set<String> tops = new HashSet<String>();
final Map<String, SvekNode> shs = new HashMap<String, SvekNode>(); final Map<String, SvekNode> shs = new HashMap<String, SvekNode>();
@ -192,7 +192,7 @@ public class Cluster implements Moveable {
} }
} }
for (Line l : lines) { for (SvekLine l : lines) {
if (tops.contains(l.getStartUidPrefix())) { if (tops.contains(l.getStartUidPrefix())) {
final SvekNode sh = shs.get(l.getEndUidPrefix()); final SvekNode sh = shs.get(l.getEndUidPrefix());
if (sh != null && sh.getEntityPosition() == EntityPosition.NORMAL) { if (sh != null && sh.getEntityPosition() == EntityPosition.NORMAL) {
@ -211,7 +211,7 @@ public class Cluster implements Moveable {
return firsts; return firsts;
} }
private List<SvekNode> getNodesOrderedWithoutTop(Collection<Line> lines) { private List<SvekNode> getNodesOrderedWithoutTop(Collection<SvekLine> lines) {
final List<SvekNode> all = new ArrayList<SvekNode>(nodes); final List<SvekNode> all = new ArrayList<SvekNode>(nodes);
final Set<String> tops = new HashSet<String>(); final Set<String> tops = new HashSet<String>();
final Map<String, SvekNode> shs = new HashMap<String, SvekNode>(); final Map<String, SvekNode> shs = new HashMap<String, SvekNode>();
@ -229,7 +229,7 @@ public class Cluster implements Moveable {
} }
} }
for (Line l : lines) { for (SvekLine l : lines) {
if (tops.contains(l.getStartUidPrefix())) { if (tops.contains(l.getStartUidPrefix())) {
final SvekNode sh = shs.get(l.getEndUidPrefix()); final SvekNode sh = shs.get(l.getEndUidPrefix());
if (sh != null) { if (sh != null) {
@ -308,7 +308,6 @@ public class Cluster implements Moveable {
if (fullName.startsWith("##") == false) { if (fullName.startsWith("##") == false) {
ug.draw(new UComment("cluster " + fullName)); ug.draw(new UComment("cluster " + fullName));
} }
final Stereotype stereotype = group.getStereotype();
HColor borderColor; HColor borderColor;
if (UseStyle.useBetaStyle()) { if (UseStyle.useBetaStyle()) {
final Style style = getDefaultStyleDefinition(umlDiagramType.getStyleName()) final Style style = getDefaultStyleDefinition(umlDiagramType.getStyleName())
@ -317,11 +316,11 @@ public class Cluster implements Moveable {
} else { } else {
if (umlDiagramType == UmlDiagramType.STATE) { if (umlDiagramType == UmlDiagramType.STATE) {
borderColor = getColor(ColorParam.stateBorder, skinParam, stereotype); borderColor = getColor(ColorParam.stateBorder, skinParam, group.getStereotype());
} else if (umlDiagramType == UmlDiagramType.ACTIVITY) { } else if (umlDiagramType == UmlDiagramType.ACTIVITY) {
borderColor = getColor(ColorParam.packageBorder, skinParam, stereotype); borderColor = getColor(ColorParam.packageBorder, skinParam, group.getStereotype());
} else { } else {
borderColor = getColor(ColorParam.packageBorder, skinParam, stereotype); borderColor = getColor(ColorParam.packageBorder, skinParam, group.getStereotype());
} }
} }
@ -374,13 +373,13 @@ public class Cluster implements Moveable {
shadowing = skinParam2.shadowing2(group.getStereotype(), group.getUSymbol().getSkinParameter()) ? 3 shadowing = skinParam2.shadowing2(group.getStereotype(), group.getUSymbol().getSkinParameter()) ? 3
: 0; : 0;
} }
stroke = getStrokeInternal(skinParam2); stroke = getStrokeInternal(group, skinParam2);
} }
HColor backColor = getBackColor(umlDiagramType); HColor backColor = getBackColor(umlDiagramType);
backColor = getBackColor(backColor, skinParam2, group.getStereotype(), umlDiagramType.getStyleName()); backColor = getBackColor(backColor, skinParam2, group.getStereotype(), umlDiagramType.getStyleName());
if (ztitle != null || zstereo != null) { if (ztitle != null || zstereo != null) {
final double roundCorner = group.getUSymbol() == null ? 0 final double roundCorner = group.getUSymbol() == null ? 0
: group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, stereotype); : group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, group.getStereotype());
final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle, final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle,
zstereo, minX, minY, maxX, maxY, stroke); zstereo, minX, minY, maxX, maxY, stroke);
@ -402,7 +401,7 @@ public class Cluster implements Moveable {
} }
private UStroke getStrokeInternal(ISkinParam skinParam) { static public UStroke getStrokeInternal(IGroup group, ISkinParam skinParam) {
final Colors colors = group.getColors(skinParam); final Colors colors = group.getColors(skinParam);
if (colors.getSpecificLineStroke() != null) { if (colors.getSpecificLineStroke() != null) {
return colors.getSpecificLineStroke(); return colors.getSpecificLineStroke();
@ -517,8 +516,8 @@ public class Cluster implements Moveable {
return fontParam.getStyleDefinition(SName.stateDiagram).getMergedStyle(skinParam.getCurrentStyleBuilder()); return fontParam.getStyleDefinition(SName.stateDiagram).getMergedStyle(skinParam.getCurrentStyleBuilder());
} }
private boolean isThereALinkFromOrToGroup(Collection<Line> lines) { private boolean isThereALinkFromOrToGroup(Collection<SvekLine> lines) {
for (Line line : lines) { for (SvekLine line : lines) {
if (line.isLinkFromOrTo(group)) { if (line.isLinkFromOrTo(group)) {
return true; return true;
} }
@ -526,7 +525,7 @@ public class Cluster implements Moveable {
return false; return false;
} }
public void printCluster1(StringBuilder sb, Collection<Line> lines, StringBounder stringBounder) { public void printCluster1(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder) {
for (SvekNode node : getNodesOrderedTop(lines)) { for (SvekNode node : getNodesOrderedTop(lines)) {
node.appendShape(sb, stringBounder); node.appendShape(sb, stringBounder);
} }
@ -618,8 +617,8 @@ public class Cluster implements Moveable {
printRanks(RANK_SINK, withPositionProtected(stringBounder, EntityPosition.getOutputs()), sb, stringBounder); printRanks(RANK_SINK, withPositionProtected(stringBounder, EntityPosition.getOutputs()), sb, stringBounder);
} }
public SvekNode printCluster2(StringBuilder sb, Collection<Line> lines, StringBounder stringBounder, DotMode dotMode, public SvekNode printCluster2(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder,
GraphvizVersion graphvizVersion, UmlDiagramType type) { DotMode dotMode, GraphvizVersion graphvizVersion, UmlDiagramType type) {
SvekNode added = null; SvekNode added = null;
for (SvekNode node : getNodesOrderedWithoutTop(lines)) { for (SvekNode node : getNodesOrderedWithoutTop(lines)) {
@ -639,16 +638,16 @@ public class Cluster implements Moveable {
return added; return added;
} }
private void appendRankSame(StringBuilder sb, Collection<Line> lines) { private void appendRankSame(StringBuilder sb, Collection<SvekLine> lines) {
for (String same : getRankSame(lines)) { for (String same : getRankSame(lines)) {
sb.append(same); sb.append(same);
SvekUtils.println(sb); SvekUtils.println(sb);
} }
} }
private Set<String> getRankSame(Collection<Line> lines) { private Set<String> getRankSame(Collection<SvekLine> lines) {
final Set<String> rankSame = new HashSet<String>(); final Set<String> rankSame = new HashSet<String>();
for (Line l : lines) { for (SvekLine l : lines) {
if (l.hasEntryPoint()) { if (l.hasEntryPoint()) {
continue; continue;
} }
@ -738,8 +737,8 @@ public class Cluster implements Moveable {
return null; return null;
} }
private void printInternal(StringBuilder sb, Collection<Line> lines, StringBounder stringBounder, DotMode dotMode, private void printInternal(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder,
GraphvizVersion graphvizVersion, UmlDiagramType type) { DotMode dotMode, GraphvizVersion graphvizVersion, UmlDiagramType type) {
final boolean thereALinkFromOrToGroup2 = isThereALinkFromOrToGroup(lines); final boolean thereALinkFromOrToGroup2 = isThereALinkFromOrToGroup(lines);
boolean thereALinkFromOrToGroup1 = thereALinkFromOrToGroup2; boolean thereALinkFromOrToGroup1 = thereALinkFromOrToGroup2;
final boolean useProtectionWhenThereALinkFromOrToGroup = graphvizVersion final boolean useProtectionWhenThereALinkFromOrToGroup = graphvizVersion
@ -753,7 +752,7 @@ public class Cluster implements Moveable {
} }
final Set<EntityPosition> entityPositionsExceptNormal = entityPositionsExceptNormal(); final Set<EntityPosition> entityPositionsExceptNormal = entityPositionsExceptNormal();
if (entityPositionsExceptNormal.size() > 0) { if (entityPositionsExceptNormal.size() > 0) {
for (Line line : lines) { for (SvekLine line : lines) {
if (line.isLinkFromOrTo(group)) { if (line.isLinkFromOrTo(group)) {
line.setProjectionCluster(this); line.setProjectionCluster(this);
} }
@ -779,7 +778,7 @@ public class Cluster implements Moveable {
final String label; final String label;
if (isLabel()) { if (isLabel()) {
final StringBuilder sblabel = new StringBuilder("<"); final StringBuilder sblabel = new StringBuilder("<");
Line.appendTable(sblabel, getTitleAndAttributeWidth(), getTitleAndAttributeHeight() - 5, colorTitle); SvekLine.appendTable(sblabel, getTitleAndAttributeWidth(), getTitleAndAttributeHeight() - 5, colorTitle);
sblabel.append(">"); sblabel.append(">");
label = sblabel.toString(); label = sblabel.toString();
final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment,

View File

@ -76,13 +76,6 @@ public class ClusterDecoration {
return style.toUSymbol(); return style.toUSymbol();
} }
public final static int marginTitleX1 = 3;
public final static int marginTitleX2 = 3;
public final static int marginTitleX3 = 7;
public final static int marginTitleY0 = 0;
public final static int marginTitleY1 = 3;
public final static int marginTitleY2 = 3;
public void drawU(UGraphic ug, HColor backColor, HColor borderColor, double shadowing, double roundCorner, public void drawU(UGraphic ug, HColor backColor, HColor borderColor, double shadowing, double roundCorner,
HorizontalAlignment titleAlignment, HorizontalAlignment stereoAlignment) { HorizontalAlignment titleAlignment, HorizontalAlignment stereoAlignment) {
final SymbolContext biColor = new SymbolContext(backColor, borderColor); final SymbolContext biColor = new SymbolContext(backColor, borderColor);
@ -91,8 +84,8 @@ public class ClusterDecoration {
} }
final SymbolContext symbolContext = biColor.withShadow(shadowing).withStroke(defaultStroke) final SymbolContext symbolContext = biColor.withShadow(shadowing).withStroke(defaultStroke)
.withCorner(roundCorner, 0); .withCorner(roundCorner, 0);
symbol.asBig(title, titleAlignment, stereo, maxX - minX, maxY - minY, symbolContext, stereoAlignment).drawU( symbol.asBig(title, titleAlignment, stereo, maxX - minX, maxY - minY, symbolContext, stereoAlignment)
ug.apply(new UTranslate(minX, minY))); .drawU(ug.apply(new UTranslate(minX, minY)));
} }
} }

View File

@ -125,7 +125,7 @@ public class DotStringFactory implements Moveable {
private double getHorizontalDzeta() { private double getHorizontalDzeta() {
double max = 0; double max = 0;
for (Line l : bibliotekon.allLines()) { for (SvekLine l : bibliotekon.allLines()) {
final double c = l.getHorizontalDzeta(stringBounder); final double c = l.getHorizontalDzeta(stringBounder);
if (c > max) { if (c > max) {
max = c; max = c;
@ -136,7 +136,7 @@ public class DotStringFactory implements Moveable {
private double getVerticalDzeta() { private double getVerticalDzeta() {
double max = 0; double max = 0;
for (Line l : bibliotekon.allLines()) { for (SvekLine l : bibliotekon.allLines()) {
final double c = l.getVerticalDzeta(stringBounder); final double c = l.getVerticalDzeta(stringBounder);
if (c > max) { if (c > max) {
max = c; max = c;
@ -207,14 +207,14 @@ public class DotStringFactory implements Moveable {
manageMinMaxCluster(sb); manageMinMaxCluster(sb);
root.printCluster1(sb, bibliotekon.allLines(), stringBounder); root.printCluster1(sb, bibliotekon.allLines(), stringBounder);
for (Line line : bibliotekon.lines0()) { for (SvekLine line : bibliotekon.lines0()) {
line.appendLine(getGraphvizVersion(), sb, dotMode); line.appendLine(getGraphvizVersion(), sb, dotMode);
} }
root.fillRankMin(rankMin); root.fillRankMin(rankMin);
root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(), umlDiagramType); root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(), umlDiagramType);
printMinRanking(sb); printMinRanking(sb);
for (Line line : bibliotekon.lines1()) { for (SvekLine line : bibliotekon.lines1()) {
line.appendLine(getGraphvizVersion(), sb, dotMode); line.appendLine(getGraphvizVersion(), sb, dotMode);
} }
SvekUtils.println(sb); SvekUtils.println(sb);
@ -442,11 +442,11 @@ public class DotStringFactory implements Moveable {
cluster.setTitlePosition(minXtitle, minYtitle); cluster.setTitlePosition(minXtitle, minYtitle);
} }
for (Line line : bibliotekon.allLines()) { for (SvekLine line : bibliotekon.allLines()) {
line.solveLine(svgResult); line.solveLine(svgResult);
} }
for (Line line : bibliotekon.allLines()) { for (SvekLine line : bibliotekon.allLines()) {
line.manageCollision(bibliotekon.allNodes()); line.manageCollision(bibliotekon.allNodes());
} }
// corner1.manage(0, 0); // corner1.manage(0, 0);
@ -493,7 +493,7 @@ public class DotStringFactory implements Moveable {
for (SvekNode sh : bibliotekon.allNodes()) { for (SvekNode sh : bibliotekon.allNodes()) {
sh.moveSvek(deltaX, deltaY); sh.moveSvek(deltaX, deltaY);
} }
for (Line line : bibliotekon.allLines()) { for (SvekLine line : bibliotekon.allLines()) {
line.moveSvek(deltaX, deltaY); line.moveSvek(deltaX, deltaY);
} }
for (Cluster cl : bibliotekon.allCluster()) { for (Cluster cl : bibliotekon.allCluster()) {

View File

@ -424,17 +424,10 @@ public final class GeneralImageBuilder {
} }
try { try {
final ISkinParam skinParam = dotData.getSkinParam(); final ISkinParam skinParam = dotData.getSkinParam();
final FontConfiguration labelFont; final FontConfiguration labelFont = getFontForLink(link, skinParam);
if (UseStyle.useBetaStyle()) {
final Style style = getDefaultStyleDefinitionArrow(link.getStereotype())
.getMergedStyle(link.getStyleBuilder());
labelFont = style.getFontConfiguration(skinParam.getIHtmlColorSet());
} else {
labelFont = new FontConfiguration(skinParam, FontParam.ARROW, null);
}
final Line line = new Line(link, dotStringFactory.getColorSequence(), skinParam, stringBounder, final SvekLine line = new SvekLine(link, dotStringFactory.getColorSequence(), skinParam, stringBounder,
labelFont, dotStringFactory.getBibliotekon(), dotData.getPragma()); labelFont, dotStringFactory.getBibliotekon(), pragma);
dotStringFactory.getBibliotekon().addLine(line); dotStringFactory.getBibliotekon().addLine(line);
@ -489,6 +482,18 @@ public final class GeneralImageBuilder {
} }
private FontConfiguration getFontForLink(Link link, final ISkinParam skinParam) {
final FontConfiguration labelFont;
if (UseStyle.useBetaStyle()) {
final Style style = getDefaultStyleDefinitionArrow(link.getStereotype())
.getMergedStyle(link.getStyleBuilder());
labelFont = style.getFontConfiguration(skinParam.getIHtmlColorSet());
} else {
labelFont = new FontConfiguration(skinParam, FontParam.ARROW, null);
}
return labelFont;
}
private boolean isSvekTrace() { private boolean isSvekTrace() {
final String value = pragma.getValue("svek_trace"); final String value = pragma.getValue("svek_trace");
return "true".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value); return "true".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value);

View File

@ -101,7 +101,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorNone; import net.sourceforge.plantuml.ugraphic.color.HColorNone;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils; import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class Line implements Moveable, Hideable, GuideLine { public class SvekLine implements Moveable, Hideable, GuideLine {
private static final Dimension2DDouble CONSTRAINT_SPOT = new Dimension2DDouble(10, 10); private static final Dimension2DDouble CONSTRAINT_SPOT = new Dimension2DDouble(10, 10);
@ -205,7 +205,7 @@ public class Line implements Moveable, Hideable, GuideLine {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
public Line(Link link, ColorSequence colorSequence, ISkinParam skinParam, StringBounder stringBounder, public SvekLine(Link link, ColorSequence colorSequence, ISkinParam skinParam, StringBounder stringBounder,
FontConfiguration font, Bibliotekon bibliotekon, Pragma pragma) { FontConfiguration font, Bibliotekon bibliotekon, Pragma pragma) {
if (link == null) { if (link == null) {
@ -985,7 +985,7 @@ public class Line implements Moveable, Hideable, GuideLine {
return link.isHidden(); return link.isHidden();
} }
public boolean sameConnections(Line other) { public boolean sameConnections(SvekLine other) {
return link.sameConnections(other.link); return link.sameConnections(other.link);
} }

View File

@ -98,7 +98,7 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage
final Set<String> ids = new HashSet<String>(); final Set<String> ids = new HashSet<String>();
for (Line line : dotStringFactory.getBibliotekon().allLines()) { for (SvekLine line : dotStringFactory.getBibliotekon().allLines()) {
final UGraphic ug2 = line.isHidden() ? ug.apply(UHidden.HIDDEN) : ug; final UGraphic ug2 = line.isHidden() ? ug.apply(UHidden.HIDDEN) : ug;
if (UseStyle.useBetaStyle()) { if (UseStyle.useBetaStyle()) {

View File

@ -53,7 +53,7 @@ import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.svek.AbstractEntityImage; import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.Bibliotekon; import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.Line; import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.svek.ShapeType;
import net.sourceforge.plantuml.ugraphic.UEllipse; import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -100,10 +100,10 @@ public class EntityImageLollipopInterfaceEye1 extends AbstractEntityImage {
Point2D pos = bibliotekon.getNode(getEntity()).getPosition(); Point2D pos = bibliotekon.getNode(getEntity()).getPosition();
final List<Line> lines = bibliotekon.getAllLineConnectedTo(getEntity()); final List<SvekLine> lines = bibliotekon.getAllLineConnectedTo(getEntity());
final UTranslate reverse = new UTranslate(pos).reverse(); final UTranslate reverse = new UTranslate(pos).reverse();
final ConnectedCircle connectedCircle = new ConnectedCircle(SIZE / 2); final ConnectedCircle connectedCircle = new ConnectedCircle(SIZE / 2);
for (Line line : lines) { for (SvekLine line : lines) {
Point2D pt = line.getMyPoint(getEntity()); Point2D pt = line.getMyPoint(getEntity());
pt = reverse.getTranslated(pt); pt = reverse.getTranslated(pt);
connectedCircle.addSecondaryConnection(pt); connectedCircle.addSecondaryConnection(pt);

View File

@ -71,7 +71,7 @@ import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleSignature; import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.svek.AbstractEntityImage; import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.Line; import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.svek.ShapeType; import net.sourceforge.plantuml.svek.ShapeType;
import net.sourceforge.plantuml.svek.SvekNode; import net.sourceforge.plantuml.svek.SvekNode;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -300,11 +300,11 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
return ShapeType.RECTANGLE; return ShapeType.RECTANGLE;
} }
private Line opaleLine; private SvekLine opaleLine;
private SvekNode node; private SvekNode node;
private SvekNode other; private SvekNode other;
public void setOpaleLine(Line line, SvekNode node, SvekNode other) { public void setOpaleLine(SvekLine line, SvekNode node, SvekNode other) {
if (other == null) { if (other == null) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }