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:
parent
dfdec8820f
commit
320ab186b4
@ -59,15 +59,19 @@ import org.eclipse.elk.graph.ElkNode;
|
||||
import org.eclipse.elk.graph.util.ElkGraphUtil;
|
||||
|
||||
import net.sourceforge.plantuml.FileFormatOption;
|
||||
import net.sourceforge.plantuml.FontParam;
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.StringUtils;
|
||||
import net.sourceforge.plantuml.UmlDiagram;
|
||||
import net.sourceforge.plantuml.api.ImageDataSimple;
|
||||
import net.sourceforge.plantuml.core.ImageData;
|
||||
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.cucadiagram.ILeaf;
|
||||
import net.sourceforge.plantuml.cucadiagram.Link;
|
||||
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.QuoteUtils;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
@ -91,6 +95,7 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
|
||||
private final DotStringFactory dotStringFactory;
|
||||
|
||||
private final Map<ILeaf, ElkNode> nodes = new LinkedHashMap<ILeaf, ElkNode>();
|
||||
private final Map<Link, ElkEdge> edges = new LinkedHashMap<Link, ElkEdge>();
|
||||
|
||||
public CucaDiagramFileMakerElk(CucaDiagram diagram, StringBounder stringBounder) {
|
||||
this.diagram = diagram;
|
||||
@ -99,6 +104,36 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
|
||||
|
||||
}
|
||||
|
||||
// Unused right now
|
||||
private TextBlock getLabel(Link link) {
|
||||
final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1;
|
||||
ISkinParam skinParam = diagram.getSkinParam();
|
||||
final FontConfiguration labelFont = new FontConfiguration(skinParam, FontParam.ARROW, null);
|
||||
final TextBlock label = link.getLabel().create(labelFont,
|
||||
skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam);
|
||||
if (TextBlockUtils.isEmpty(label, stringBounder)) {
|
||||
return label;
|
||||
}
|
||||
return TextBlockUtils.withMargin(label, marginLabel, marginLabel);
|
||||
}
|
||||
|
||||
// Unused right now
|
||||
private TextBlock getQualifier(Link link, int n) {
|
||||
final String tmp = n == 1 ? link.getQualifier1() : link.getQualifier2();
|
||||
if (tmp == null) {
|
||||
return null;
|
||||
}
|
||||
final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1;
|
||||
ISkinParam skinParam = diagram.getSkinParam();
|
||||
final FontConfiguration labelFont = new FontConfiguration(skinParam, FontParam.ARROW, null);
|
||||
final TextBlock label = Display.getWithNewlines(tmp).create(labelFont,
|
||||
skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam);
|
||||
if (TextBlockUtils.isEmpty(label, stringBounder)) {
|
||||
return label;
|
||||
}
|
||||
return TextBlockUtils.withMargin(label, marginLabel, marginLabel);
|
||||
}
|
||||
|
||||
// The Drawing class does the real drawing
|
||||
class Drawing extends AbstractTextBlock implements TextBlockBackcolored {
|
||||
|
||||
@ -125,6 +160,17 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
|
||||
image.drawU(ug.apply(new UTranslate(corner)));
|
||||
}
|
||||
|
||||
// Draw all edges
|
||||
for (Entry<Link, ElkEdge> ent : edges.entrySet()) {
|
||||
final Link link = ent.getKey();
|
||||
if (link.isInvis()) {
|
||||
continue;
|
||||
}
|
||||
final ElkEdge edge = ent.getValue();
|
||||
new ElkPath(link, edge, diagram, getLabel(link), getQualifier(link, 1), getQualifier(link, 2))
|
||||
.drawU(ug);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder) {
|
||||
@ -146,7 +192,9 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
|
||||
|
||||
try {
|
||||
final ElkNode root = ElkGraphUtil.createGraph();
|
||||
final ElkPadding labelPadding = new ElkPadding(2.0);
|
||||
|
||||
// This padding setting have no impact ?
|
||||
final ElkPadding labelPadding = new ElkPadding(100.0);
|
||||
|
||||
// Convert all "leaf" to ELK node
|
||||
for (ILeaf leaf : diagram.getLeafsvalues()) {
|
||||
@ -162,7 +210,11 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
|
||||
// There is no real "label" here
|
||||
// We just would like to force node dimension
|
||||
final ElkLabel label = ElkGraphUtil.createLabel(node);
|
||||
label.setDimensions(dimension.getWidth(), dimension.getHeight());
|
||||
label.setText("X");
|
||||
|
||||
// I don't know why we have to do this hack, but somebody has to fix it
|
||||
final double VERY_STRANGE_OFFSET = 10;
|
||||
label.setDimensions(dimension.getWidth() - VERY_STRANGE_OFFSET, dimension.getHeight());
|
||||
|
||||
// No idea of what we are doing here :-)
|
||||
label.setProperty(CoreOptions.NODE_LABELS_PLACEMENT, EnumSet.of(NodeLabelPlacement.INSIDE,
|
||||
@ -175,22 +227,31 @@ public class CucaDiagramFileMakerElk implements CucaDiagramFileMaker {
|
||||
nodes.put(leaf, node);
|
||||
}
|
||||
|
||||
// https://www.eclipse.org/forums/index.php/t/1095737/
|
||||
|
||||
for (final Link link : diagram.getLinks()) {
|
||||
final ElkEdge edge = ElkGraphUtil.createEdge(root);
|
||||
System.err.println("edge=" + edge);
|
||||
edge.getSources().add(nodes.get(link.getEntity1()));
|
||||
edge.getTargets().add(nodes.get(link.getEntity2()));
|
||||
edges.put(link, edge);
|
||||
}
|
||||
|
||||
final RecursiveGraphLayoutEngine engine = new RecursiveGraphLayoutEngine();
|
||||
engine.layout(root, new NullElkProgressMonitor());
|
||||
|
||||
// Debug
|
||||
for (final ElkNode node : nodes.values()) {
|
||||
final String name = node.getLabels().get(0).getText();
|
||||
System.out.println("node " + name + " : " + node.getX() + ", " + node.getY() + " (" + node.getWidth()
|
||||
+ ", " + node.getHeight() + ")");
|
||||
}
|
||||
// for (final ElkNode node : nodes.values()) {
|
||||
// final String name = node.getLabels().get(0).getText();
|
||||
// System.out.println("node " + name + " : " + node.getX() + ", " + node.getY() + " (" + node.getWidth()
|
||||
// + ", " + node.getHeight() + ")");
|
||||
// }
|
||||
// for (final ElkEdge edge : edges.values()) {
|
||||
// final EList<ElkEdgeSection> sections = edge.getSections();
|
||||
// System.out.println("edge=" + edge.getSections());
|
||||
// System.out.println("edge=" + edge.getProperty(LayeredOptions.JUNCTION_POINTS));
|
||||
// for (ElkEdgeSection s : sections)
|
||||
// System.out.println(s.getBendPoints());
|
||||
// }
|
||||
|
||||
final MinMax minMax = TextBlockUtils.getMinMax(new Drawing(null), stringBounder, false);
|
||||
|
||||
|
147
src/net/sourceforge/plantuml/elk/ElkPath.java
Normal file
147
src/net/sourceforge/plantuml/elk/ElkPath.java
Normal file
@ -0,0 +1,147 @@
|
||||
/* ========================================================================
|
||||
* 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;
|
||||
|
||||
import org.eclipse.elk.graph.ElkBendPoint;
|
||||
import org.eclipse.elk.graph.ElkEdge;
|
||||
import org.eclipse.elk.graph.ElkEdgeSection;
|
||||
import org.eclipse.emf.common.util.EList;
|
||||
|
||||
import net.sourceforge.plantuml.ColorParam;
|
||||
import net.sourceforge.plantuml.LineParam;
|
||||
import net.sourceforge.plantuml.UmlDiagramType;
|
||||
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
|
||||
import net.sourceforge.plantuml.cucadiagram.Link;
|
||||
import net.sourceforge.plantuml.cucadiagram.LinkType;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.graphic.color.ColorType;
|
||||
import net.sourceforge.plantuml.skin.rose.Rose;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
||||
|
||||
public class ElkPath implements UDrawable {
|
||||
|
||||
private final Link link;
|
||||
private final ElkEdge edge;
|
||||
|
||||
private final CucaDiagram diagram;
|
||||
private final TextBlock label;
|
||||
private final TextBlock headLabel;
|
||||
private final TextBlock tailLabel;
|
||||
private final Rose rose = new Rose();
|
||||
|
||||
public ElkPath(Link link, ElkEdge edge, CucaDiagram diagram, TextBlock label, TextBlock tailLabel,
|
||||
TextBlock headLabel) {
|
||||
this.link = link;
|
||||
this.edge = edge;
|
||||
|
||||
this.diagram = diagram;
|
||||
this.label = label;
|
||||
this.tailLabel = tailLabel;
|
||||
this.headLabel = headLabel;
|
||||
}
|
||||
|
||||
private ColorParam getArrowColorParam() {
|
||||
if (diagram.getUmlDiagramType() == UmlDiagramType.CLASS) {
|
||||
return ColorParam.arrow;
|
||||
} else if (diagram.getUmlDiagramType() == UmlDiagramType.OBJECT) {
|
||||
return ColorParam.arrow;
|
||||
} else if (diagram.getUmlDiagramType() == UmlDiagramType.DESCRIPTION) {
|
||||
return ColorParam.arrow;
|
||||
} else if (diagram.getUmlDiagramType() == UmlDiagramType.ACTIVITY) {
|
||||
return ColorParam.arrow;
|
||||
} else if (diagram.getUmlDiagramType() == UmlDiagramType.STATE) {
|
||||
return ColorParam.arrow;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
|
||||
if (link.isHidden()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HColor color = rose.getHtmlColor(diagram.getSkinParam(), null, getArrowColorParam());
|
||||
|
||||
if (this.link.getColors() != null) {
|
||||
final HColor newColor = this.link.getColors().getColor(ColorType.ARROW, ColorType.LINE);
|
||||
if (newColor != null) {
|
||||
color = newColor;
|
||||
}
|
||||
|
||||
} else if (this.link.getSpecificColor() != null) {
|
||||
color = this.link.getSpecificColor();
|
||||
}
|
||||
|
||||
final LinkType linkType = link.getType();
|
||||
UStroke stroke = linkType.getStroke3(diagram.getSkinParam().getThickness(LineParam.arrow, null));
|
||||
if (link.getColors() != null && link.getColors().getSpecificLineStroke() != null) {
|
||||
stroke = link.getColors().getSpecificLineStroke();
|
||||
}
|
||||
ug = ug.apply(stroke).apply(color);
|
||||
|
||||
final EList<ElkEdgeSection> sections = edge.getSections();
|
||||
|
||||
for (ElkEdgeSection section : sections) {
|
||||
|
||||
final EList<ElkBendPoint> points = section.getBendPoints();
|
||||
|
||||
double x1 = section.getStartX();
|
||||
double y1 = section.getStartY();
|
||||
|
||||
for (ElkBendPoint pt : points) {
|
||||
drawLine(ug, x1, y1, pt.getX(), pt.getY());
|
||||
x1 = pt.getX();
|
||||
y1 = pt.getY();
|
||||
}
|
||||
|
||||
drawLine(ug, x1, y1, section.getEndX(), section.getEndY());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawLine(UGraphic ug, final double x1, final double y1, final double x2, final double y2) {
|
||||
final ULine line = new ULine(x2 - x1, y2 - y1);
|
||||
ug.apply(new UTranslate(x1, y1)).draw(line);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user