Scxml improvement

This commit is contained in:
Arnaud Roques 2022-09-06 10:49:43 +02:00
parent a562d24aa4
commit 847f482609
20 changed files with 703 additions and 240 deletions

View File

@ -47,6 +47,8 @@ import net.sourceforge.plantuml.security.SecurityUtils;
public class OptionFlags {
static public final boolean USE_KERMOR = false;
private static final OptionFlags singleton = new OptionFlags();
// static public final boolean PBBACK = false;

View File

@ -197,9 +197,8 @@ public class CommandLinkActivity extends SingleLineCommand2<ActivityDiagram> {
if (arg.get("STAR" + suf, 0) != null) {
final String suppId = arg.get("STAR" + suf, 1);
if (start) {
if (suppId != null)
diagram.getStart().setTop(true);
// if (suppId != null)
// diagram.getStart().setTop(true);
return diagram.getStart();
}
return diagram.getEnd(suppId);

View File

@ -37,6 +37,7 @@ package net.sourceforge.plantuml.command.note;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.UrlBuilder;
@ -227,6 +228,24 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
}
}
final Position position = Position.valueOf(StringUtils.goUpperCase(pos))
.withRankdir(diagram.getSkinParam().getRankdir());
Colors colors = color().getColor(diagram.getSkinParam().getThemeStyle(), line0,
diagram.getSkinParam().getIHtmlColorSet());
final String stereotypeString = line0.get("STEREO", 0);
Stereotype stereotype = null;
if (stereotypeString != null) {
stereotype = Stereotype.build(stereotypeString);
colors = colors.applyStereotypeForNote(stereotype, diagram.getSkinParam(), ColorParam.noteBackground,
ColorParam.noteBorder);
}
if (OptionFlags.USE_KERMOR && cl1.isGroup()) {
cl1.addNote(strings.toDisplay(), position, colors);
return CommandExecutionResult.ok();
}
final String tmp = diagram.getUniqueSequence("GMN");
final Ident idNewLong = diagram.buildLeafIdent(tmp);
final IEntity note;
@ -235,16 +254,8 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
else
note = diagram.createLeaf(idNewLong, diagram.buildCode(tmp), strings.toDisplay(), LeafType.NOTE, null);
Colors colors = color().getColor(diagram.getSkinParam().getThemeStyle(), line0,
diagram.getSkinParam().getIHtmlColorSet());
final String stereotypeString = line0.get("STEREO", 0);
if (stereotypeString != null) {
final Stereotype stereotype = Stereotype.build(stereotypeString);
colors = colors.applyStereotypeForNote(stereotype, diagram.getSkinParam(), ColorParam.noteBackground,
ColorParam.noteBorder);
if (stereotypeString != null)
note.setStereotype(stereotype);
}
note.setColors(colors);
if (url != null)
@ -252,8 +263,6 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
CommandCreateClassMultilines.addTags(note, line0.get("TAGS", 0));
final Position position = Position.valueOf(StringUtils.goUpperCase(pos))
.withRankdir(diagram.getSkinParam().getRankdir());
final Link link;
final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).goDashed();

View File

@ -52,6 +52,7 @@ import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.cucadiagram.CucaNote;
import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.graphic.color.ColorParser;
import net.sourceforge.plantuml.graphic.color.ColorType;
@ -132,13 +133,13 @@ public final class CommandFactoryNoteOnLink implements SingleMultiFactoryCommand
private CommandExecutionResult executeInternal(CucaDiagram diagram, BlocLines note, final RegexResult arg)
throws NoSuchColorException {
final Link link = diagram.getLastLink();
if (link == null) {
if (link == null)
return CommandExecutionResult.error("No link defined");
}
Position position = Position.BOTTOM;
if (arg.get("POSITION", 0) != null) {
if (arg.get("POSITION", 0) != null)
position = Position.valueOf(StringUtils.goUpperCase(arg.get("POSITION", 0)));
}
Url url = null;
if (arg.get("URL", 0) != null) {
final UrlBuilder urlBuilder = new UrlBuilder(diagram.getSkinParam().getValue("topurl"), UrlMode.STRICT);
@ -146,7 +147,7 @@ public final class CommandFactoryNoteOnLink implements SingleMultiFactoryCommand
}
final Colors colors = color().getColor(diagram.getSkinParam().getThemeStyle(), arg,
diagram.getSkinParam().getIHtmlColorSet());
link.addNote(note.toDisplay(), position, colors);
link.addNote(CucaNote.build(note.toDisplay(), position, colors));
return CommandExecutionResult.ok();
}

View File

@ -0,0 +1,79 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2023, 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.cucadiagram;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.graphic.color.Colors;
public class CucaNote {
private final Display display;
private final Position position;
private final Colors colors;
private final NoteLinkStrategy strategy;
private CucaNote(Display display, Position position, Colors colors, NoteLinkStrategy strategy) {
this.display = display;
this.position = position;
this.colors = colors;
this.strategy = strategy;
}
public static CucaNote build(Display display, Position position, Colors colors) {
return new CucaNote(display, position, colors, NoteLinkStrategy.NORMAL);
}
public CucaNote withStrategy(NoteLinkStrategy strategy) {
return new CucaNote(display, position, colors, strategy);
}
public final Display getDisplay() {
return display;
}
public final NoteLinkStrategy getStrategy() {
return strategy;
}
public final Colors getColors() {
return colors;
}
public final Position getPosition() {
return position;
}
}

View File

@ -55,6 +55,30 @@ public enum EntityPosition {
public static final double RADIUS = 6;
public static EnumSet<EntityPosition> getInputs() {
return EnumSet.of(ENTRY_POINT, INPUT_PIN, EXPANSION_INPUT, PORTIN);
}
public static EnumSet<EntityPosition> getOutputs() {
return EnumSet.of(EXIT_POINT, OUTPUT_PIN, EXPANSION_OUTPUT, PORTOUT);
}
public static EnumSet<EntityPosition> getNormals() {
return EnumSet.of(NORMAL);
}
public boolean isNormal() {
return this == NORMAL;
}
public boolean isInput() {
return getInputs().contains(this);
}
public boolean isOutput() {
return getOutputs().contains(this);
}
public void drawSymbol(UGraphic ug, Rankdir rankdir) {
if (this == NORMAL) {
throw new IllegalStateException();
@ -70,7 +94,7 @@ public enum EntityPosition {
drawLine(ug, getPointOnCircle(xc, yc, -Math.PI / 4, radius),
getPointOnCircle(xc, yc, Math.PI - Math.PI / 4, radius));
}
} else if (this == INPUT_PIN || this == OUTPUT_PIN /*|| this == PORT*/) {
} else if (this == INPUT_PIN || this == OUTPUT_PIN /* || this == PORT */) {
final Shadowable rectangle = new URectangle(RADIUS * 2, RADIUS * 2);
ug.draw(rectangle);
} else if (this == EXPANSION_INPUT || this == EXPANSION_OUTPUT) {
@ -151,20 +175,12 @@ public enum EntityPosition {
return EntityPosition.NORMAL;
}
public static EnumSet<EntityPosition> getInputs() {
return EnumSet.of(ENTRY_POINT, INPUT_PIN, EXPANSION_INPUT, PORTIN);
}
public static EnumSet<EntityPosition> getOutputs() {
return EnumSet.of(EXIT_POINT, OUTPUT_PIN, EXPANSION_OUTPUT, PORTOUT);
}
// public static EnumSet<EntityPosition> getSame() {
// return EnumSet.of(PORT);
// }
//
public boolean isPort() {
return /*this == PORT ||*/ this == PORTIN || this == PORTOUT;
return /* this == PORT || */ this == PORTIN || this == PORTOUT;
}
public boolean usePortP() {

View File

@ -45,6 +45,7 @@ import java.util.Set;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.cucadiagram.entity.EntityFactory;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.USymbol;
@ -334,4 +335,19 @@ public class GroupRoot implements IGroup {
public Stereostyles getStereostyles() {
throw new UnsupportedOperationException();
}
@Override
public void addNote(Display note, Position position, Colors colors) {
throw new UnsupportedOperationException();
}
@Override
public EntityPosition getEntityPosition() {
throw new UnsupportedOperationException();
}
@Override
public List<CucaNote> getNotes() {
throw new UnsupportedOperationException();
}
}

View File

@ -35,6 +35,7 @@
*/
package net.sourceforge.plantuml.cucadiagram;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -44,7 +45,9 @@ import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.Removeable;
import net.sourceforge.plantuml.SpecificBackcolorable;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.graphic.color.Colors;
public interface IEntity extends SpecificBackcolorable, Hideable, Removeable, LineConfigurable {
@ -104,4 +107,10 @@ public interface IEntity extends SpecificBackcolorable, Hideable, Removeable, Li
public Stereostyles getStereostyles();
public void addNote(Display note, Position position, Colors colors);
public EntityPosition getEntityPosition();
public List<CucaNote> getNotes();
}

View File

@ -49,10 +49,6 @@ public interface ILeaf extends IEntity {
public void setContainer(IGroup container);
public boolean isTop();
public void setTop(boolean top);
public Margins getMargins();
public int getXposition();

View File

@ -45,14 +45,12 @@ import net.sourceforge.plantuml.Removeable;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.awt.geom.Dimension2D;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.USymbolInterface;
import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.skin.VisibilityModifier;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.Bibliotekon;
@ -75,10 +73,7 @@ public class Link extends WithLinkType implements Hideable, Removeable {
final private String uid;
private Display note;
private Position notePosition;
private Colors noteColors;
private NoteLinkStrategy noteLinkStrategy;
private CucaNote note;
private boolean invis = false;
private double weight = 1.0;
@ -125,6 +120,11 @@ public class Link extends WithLinkType implements Hideable, Removeable {
this.uid = "LNK" + ((EntityImpl) cl1).getDiagram().getUniqueSequence();
this.linkArg = linkArg;
if (OptionFlags.USE_KERMOR) {
if (cl1.getEntityPosition().isNormal() == false ^ cl2.getEntityPosition().isNormal() == false)
setConstraint(false);
}
}
public Link getInv() {
@ -293,34 +293,17 @@ public class Link extends WithLinkType implements Hideable, Removeable {
this.weight = weight;
}
public final Display getNote() {
public final CucaNote getNote() {
return note;
}
public final NoteLinkStrategy getNoteLinkStrategy() {
return noteLinkStrategy;
}
public final Colors getNoteColors() {
return noteColors;
}
public final Position getNotePosition() {
return notePosition;
}
public final void addNote(Display note, Position position, Colors colors) {
public final void addNote(CucaNote note) {
this.note = note;
this.notePosition = position;
this.noteColors = colors;
this.noteLinkStrategy = NoteLinkStrategy.NORMAL;
}
public final void addNoteFrom(Link other, NoteLinkStrategy strategy) {
this.note = other.note;
this.notePosition = other.notePosition;
this.noteColors = other.noteColors;
this.noteLinkStrategy = strategy;
if (other.note != null)
this.note = other.note.withStrategy(strategy);
}
public boolean isAutoLinkOfAGroup() {
@ -419,15 +402,14 @@ public class Link extends WithLinkType implements Hideable, Removeable {
}
public boolean hasEntryPoint() {
return (getEntity1().isGroup() == false && ((ILeaf) getEntity1()).getEntityPosition() != EntityPosition.NORMAL)
|| (getEntity2().isGroup() == false
&& ((ILeaf) getEntity2()).getEntityPosition() != EntityPosition.NORMAL);
return (getEntity1().isGroup() == false && getEntity1().getEntityPosition() != EntityPosition.NORMAL)
|| (getEntity2().isGroup() == false && getEntity2().getEntityPosition() != EntityPosition.NORMAL);
}
public boolean hasTwoEntryPointsSameContainer() {
return getEntity1().isGroup() == false && getEntity2().isGroup() == false
&& ((ILeaf) getEntity1()).getEntityPosition() != EntityPosition.NORMAL
&& ((ILeaf) getEntity2()).getEntityPosition() != EntityPosition.NORMAL
&& getEntity1().getEntityPosition() != EntityPosition.NORMAL
&& getEntity2().getEntityPosition() != EntityPosition.NORMAL
&& getEntity1().getParentContainer() == getEntity2().getParentContainer();
}

View File

@ -55,9 +55,11 @@ import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.cucadiagram.Bodier;
import net.sourceforge.plantuml.cucadiagram.Code;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.cucadiagram.CucaNote;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.DisplayPositioned;
import net.sourceforge.plantuml.cucadiagram.EntityPosition;
@ -108,8 +110,6 @@ final public class EntityImpl implements ILeaf, IGroup {
private String generic;
private IGroup parentContainer;
private boolean top;
// Group
private Code namespace;
@ -127,6 +127,17 @@ final public class EntityImpl implements ILeaf, IGroup {
private LineLocation codeLine;
private Set<Stereotag> tags = new LinkedHashSet<>();
private final List<CucaNote> notes = new ArrayList<>();
@Override
public void addNote(Display note, Position position, Colors colors) {
notes.add(CucaNote.build(note, position, colors));
}
@Override
public List<CucaNote> getNotes() {
return Collections.unmodifiableList(notes);
}
public void addStereotag(Stereotag tag) {
this.tags.add(tag);
@ -137,16 +148,6 @@ final public class EntityImpl implements ILeaf, IGroup {
}
// Back to Entity
public final boolean isTop() {
checkNotGroup();
return top;
}
public final void setTop(boolean top) {
checkNotGroup();
this.top = top;
}
private EntityImpl(Ident ident, EntityFactory entityFactory, Code code, Bodier bodier, IGroup parentContainer,
String namespaceSeparator, int rawLayout) {
this.ident = Objects.requireNonNull(ident);

View File

@ -52,11 +52,13 @@ import java.util.Set;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.awt.geom.Dimension2D;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
import net.sourceforge.plantuml.cucadiagram.CucaNote;
import net.sourceforge.plantuml.cucadiagram.EntityPosition;
import net.sourceforge.plantuml.cucadiagram.EntityUtils;
import net.sourceforge.plantuml.cucadiagram.IEntity;
@ -76,6 +78,7 @@ import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.svek.image.EntityImageNoteLink;
import net.sourceforge.plantuml.svek.image.EntityImageState;
import net.sourceforge.plantuml.ugraphic.UComment;
import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -101,6 +104,8 @@ public class Cluster implements Moveable {
private final List<Cluster> children = new ArrayList<>();
private final int color;
private final int colorTitle;
private final int colorNoteUp;
private final int colorNoteDown;
private final ISkinParam skinParam;
protected final CucaDiagram diagram;
@ -112,17 +117,22 @@ public class Cluster implements Moveable {
private double xTitle;
private double yTitle;
private double xNoteup;
private double yNoteup;
private double minX;
private double minY;
private double maxX;
private double maxY;
public void moveSvek(double deltaX, double deltaY) {
this.xNoteup += deltaX;
this.yNoteup += deltaY;
this.xTitle += deltaX;
this.minX += deltaX;
this.maxX += deltaX;
this.yTitle += deltaY;
this.minX += deltaX;
this.minY += deltaY;
this.maxX += deltaX;
this.maxY += deltaY;
}
@ -151,6 +161,8 @@ public class Cluster implements Moveable {
this.color = colorSequence.getValue();
this.colorTitle = colorSequence.getValue();
this.colorNoteUp = colorSequence.getValue();
this.colorNoteDown = colorSequence.getValue();
this.skinParam = group.getColors().mute(skinParam);
}
@ -172,27 +184,24 @@ public class Cluster implements Moveable {
return Collections.unmodifiableList(nodes);
}
public final List<SvekNode> getNodes(EnumSet<EntityPosition> position) {
final List<SvekNode> result = new ArrayList<>();
for (SvekNode node : nodes)
if (position.contains(node.getEntityPosition()))
result.add(node);
return Collections.unmodifiableList(result);
}
private List<SvekNode> getNodesOrderedTop(Collection<SvekLine> lines) {
final List<SvekNode> firsts = new ArrayList<>();
final Set<String> tops = new HashSet<>();
final Map<String, SvekNode> shs = new HashMap<String, SvekNode>();
for (final Iterator<SvekNode> it = nodes.iterator(); it.hasNext();) {
final SvekNode node = it.next();
shs.put(node.getUid(), node);
if (node.isTop() && node.getEntityPosition() == EntityPosition.NORMAL) {
firsts.add(node);
tops.add(node.getUid());
}
}
for (SvekLine l : lines) {
if (tops.contains(l.getStartUidPrefix())) {
final SvekNode sh = shs.get(l.getEndUidPrefix());
if (sh != null && sh.getEntityPosition() == EntityPosition.NORMAL)
firsts.add(0, sh);
}
if (l.isInverted()) {
final SvekNode sh = shs.get(l.getStartUidPrefix());
if (sh != null && sh.getEntityPosition() == EntityPosition.NORMAL)
@ -205,7 +214,6 @@ public class Cluster implements Moveable {
private List<SvekNode> getNodesOrderedWithoutTop(Collection<SvekLine> lines) {
final List<SvekNode> all = new ArrayList<>(nodes);
final Set<String> tops = new HashSet<>();
final Map<String, SvekNode> shs = new HashMap<String, SvekNode>();
for (final Iterator<SvekNode> it = all.iterator(); it.hasNext();) {
@ -215,19 +223,9 @@ public class Cluster implements Moveable {
continue;
}
shs.put(sh.getUid(), sh);
if (sh.isTop()) {
tops.add(sh.getUid());
it.remove();
}
}
for (SvekLine l : lines) {
if (tops.contains(l.getStartUidPrefix())) {
final SvekNode sh = shs.get(l.getEndUidPrefix());
if (sh != null)
all.remove(sh);
}
if (l.isInverted()) {
final SvekNode sh = shs.get(l.getStartUidPrefix());
if (sh != null)
@ -281,9 +279,14 @@ public class Cluster implements Moveable {
return new ClusterPosition(minX, minY, maxX, maxY);
}
public void setTitlePosition(double x, double y) {
this.xTitle = x;
this.yTitle = y;
public void setTitlePosition(Point2D pos) {
this.xTitle = pos.getX();
this.yTitle = pos.getY();
}
public void setNoteUpPosition(Point2D pos) {
this.xNoteup = pos.getX();
this.yNoteup = pos.getY();
}
static public StyleSignatureBasic getDefaultStyleDefinition(SName diagramStyleName, USymbol symbol) {
@ -305,6 +308,12 @@ public class Cluster implements Moveable {
if (group.isHidden())
return;
if (OptionFlags.USE_KERMOR) {
if (xNoteup > 0 && yNoteup > 0) {
getCucaNote().drawU(ug.apply(new UTranslate(xNoteup, yNoteup)));
}
}
final String fullName = group.getCodeGetName();
if (fullName.startsWith("##") == false)
ug.draw(new UComment("cluster " + fullName));
@ -371,6 +380,14 @@ public class Cluster implements Moveable {
}
}
EntityImageNoteLink getCucaNote() {
if (getGroup().getNotes().size() == 0)
return null;
final CucaNote note = getGroup().getNotes().get(0);
return new EntityImageNoteLink(note.getDisplay(), note.getColors(), skinParam,
skinParam.getCurrentStyleBuilder());
}
static public UStroke getStrokeInternal(IGroup group, Style style) {
final Colors colors = group.getColors();
if (colors.getSpecificLineStroke() != null)
@ -496,6 +513,14 @@ public class Cluster implements Moveable {
}
public void setPosition(Point2D min, Point2D max) {
this.minX = min.getX();
this.minY = min.getY();
this.maxX = max.getX();
this.maxY = max.getY();
}
@Deprecated
public void setPosition(double minX, double minY, double maxX, double maxY) {
this.minX = minX;
this.maxX = maxX;
@ -503,9 +528,13 @@ public class Cluster implements Moveable {
this.maxY = maxY;
}
public void printCluster1(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder) {
for (SvekNode node : getNodesOrderedTop(lines))
public boolean printCluster1(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder) {
final List<SvekNode> tmp = getNodesOrderedTop(lines);
if (tmp.size() == 0)
return false;
for (SvekNode node : tmp)
node.appendShape(sb, stringBounder);
return true;
}
@ -528,6 +557,22 @@ public class Cluster implements Moveable {
return added;
}
public void printCluster3_forKermor(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder,
DotMode dotMode, GraphvizVersion graphvizVersion, UmlDiagramType type) {
final List<SvekNode> tmp = getNodes(EntityPosition.getNormals());
if (tmp.size() == 0) {
sb.append(getClusterId() + "empty [shape=point,label=\"\"];");
SvekUtils.println(sb);
} else
for (SvekNode node : tmp) {
node.appendShape(sb, stringBounder);
}
for (Cluster child : getChildren())
child.printInternal(sb, lines, stringBounder, dotMode, graphvizVersion, type);
}
private void printInternal(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder,
DotMode dotMode, GraphvizVersion graphvizVersion, UmlDiagramType type) {
new ClusterDotString(this, skinParam).printInternal(sb, lines, stringBounder, dotMode, graphvizVersion, type);
@ -558,16 +603,6 @@ public class Cluster implements Moveable {
return rankSame;
}
void fillRankMin(Set<String> rankMin) {
for (SvekNode sh : getNodes())
if (sh.isTop())
rankMin.add(sh.getUid());
for (Cluster child : getChildren())
child.fillRankMin(rankMin);
}
private boolean isInCluster(String uid) {
for (SvekNode node : nodes)
if (node.getUid().equals(uid))
@ -670,6 +705,14 @@ public class Cluster implements Moveable {
return 0;
}
public final int getColorNoteUp() {
return colorNoteUp;
}
public final int getColorNoteDown() {
return colorNoteDown;
}
// public Point2D projection(double x, double y) {
// final double v1 = Math.abs(minX - x);
// final double v2 = Math.abs(maxX - x);

View File

@ -46,6 +46,7 @@ import java.util.Set;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.cucadiagram.EntityPosition;
@ -67,6 +68,11 @@ public class ClusterDotString {
void printInternal(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder, DotMode dotMode,
GraphvizVersion graphvizVersion, UmlDiagramType type) {
if (OptionFlags.USE_KERMOR) {
new ClusterDotStringKermor(cluster, skinParam).printInternal(sb, lines, stringBounder, dotMode,
graphvizVersion, type);
return;
}
final boolean thereALinkFromOrToGroup2 = isThereALinkFromOrToGroup(lines);
boolean thereALinkFromOrToGroup1 = thereALinkFromOrToGroup2;
final boolean useProtectionWhenThereALinkFromOrToGroup = graphvizVersion
@ -112,7 +118,8 @@ public class ClusterDotString {
}
if (entityPositionsExceptNormal.size() > 0) {
printClusterEntryExit(sb, stringBounder);
printRanks(Cluster.RANK_SOURCE, withPosition(EntityPosition.getInputs()), sb, stringBounder);
printRanks(Cluster.RANK_SINK, withPosition(EntityPosition.getOutputs()), sb, stringBounder);
if (hasPort())
subgraphClusterNoLabel(sb, ID_EE);
else
@ -225,13 +232,6 @@ public class ClusterDotString {
sb.append("label=" + label + ";");
}
private void printClusterEntryExit(StringBuilder sb, StringBounder stringBounder) {
printRanks(Cluster.RANK_SOURCE, withPosition(EntityPosition.getInputs()), sb, stringBounder);
// printRanks(Cluster.RANK_SAME, withPosition(EntityPosition.getSame()), sb,
// stringBounder);
printRanks(Cluster.RANK_SINK, withPosition(EntityPosition.getOutputs()), sb, stringBounder);
}
private void printRanks(String rank, List<? extends SvekNode> entries, StringBuilder sb,
StringBounder stringBounder) {
if (entries.size() > 0) {

View File

@ -0,0 +1,267 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2023, 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
* Contribution : Hisashi Miyashita
*
*
*/
package net.sourceforge.plantuml.svek;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.awt.geom.Dimension2D;
import net.sourceforge.plantuml.cucadiagram.CucaNote;
import net.sourceforge.plantuml.cucadiagram.EntityPosition;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.USymbols;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.image.EntityImageNoteLink;
public class ClusterDotStringKermor {
private final Cluster cluster;
private final ISkinParam skinParam;
private static final String ID_EE = "ee";
public ClusterDotStringKermor(Cluster cluster, ISkinParam skinParam) {
this.cluster = cluster;
this.skinParam = skinParam;
}
void printInternal(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder, DotMode dotMode,
GraphvizVersion graphvizVersion, UmlDiagramType type) {
final Set<EntityPosition> entityPositionsExceptNormal = entityPositionsExceptNormal();
if (entityPositionsExceptNormal.size() > 0)
for (SvekLine line : lines)
if (line.isLinkFromOrTo(cluster.getGroup()))
line.setProjectionCluster(cluster);
final boolean useAlphaAndBeta = useAlphaAndBeta();
if (useAlphaAndBeta) {
sb.append("subgraph " + cluster.getClusterId() + "alpha {");
SvekUtils.println(sb);
final TextBlock noteOnly = cluster.getCucaNote();
if (noteOnly == null) {
sb.append("label=\"\";color=\"#FFFF00\";");
SvekUtils.println(sb);
} else {
final Dimension2D dim = noteOnly.calculateDimension(stringBounder);
System.err.println("dim=" + dim);
final StringBuilder sblabel = new StringBuilder("<");
SvekLine.appendTable(sblabel, (int) dim.getWidth(), (int) dim.getHeight(), cluster.getColorNoteUp());
sblabel.append(">");
sb.append("label=" + sblabel + ";");
sb.append("color=\"#FFFF00\";");
}
}
sb.append("subgraph " + cluster.getClusterId() + "beta {");
SvekUtils.println(sb);
sb.append("label=\"\";color=\"#FFFF00\";");
// sb.append("label=\"NOTEDOWN\";labelloc=\"b\";");
SvekUtils.println(sb);
printRanks(Cluster.RANK_SOURCE, cluster.getNodes(EntityPosition.getInputs()), sb, stringBounder);
SvekUtils.println(sb);
sb.append("subgraph " + cluster.getClusterId() + "gamma {");
SvekUtils.println(sb);
sb.append("labelloc=\"t\";");
SvekUtils.println(sb);
sb.append("style=solid;");
SvekUtils.println(sb);
sb.append("color=\"" + StringUtils.sharp000000(cluster.getColor()) + "\";");
final String label;
if (cluster.isLabel()) {
final StringBuilder sblabel = new StringBuilder("<");
SvekLine.appendTable(sblabel, cluster.getTitleAndAttributeWidth(), cluster.getTitleAndAttributeHeight() - 5,
cluster.getTitleColor());
sblabel.append(">");
label = sblabel.toString();
final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment,
null, false, null);
sb.append("labeljust=\"" + align.getGraphVizValue() + "\";");
} else {
label = "\"\"";
}
sb.append("label=" + label + ";");
SvekUtils.println(sb);
cluster.printCluster3_forKermor(sb, lines, stringBounder, dotMode, graphvizVersion, type);
SvekUtils.println(sb);
printRanks(Cluster.RANK_SINK, cluster.getNodes(EntityPosition.getOutputs()), sb, stringBounder);
SvekUtils.println(sb);
sb.append("}");
sb.append("}");
if (useAlphaAndBeta) {
sb.append("}");
}
SvekUtils.println(sb);
}
private boolean useAlphaAndBeta() {
if (cluster.getGroup().getNotes().size() > 0)
return true;
return false;
}
private String getSourceInPoint(UmlDiagramType type) {
if (skinParam.useSwimlanes(type))
return "sourceIn" + cluster.getColor();
return null;
}
private String getSinkInPoint(UmlDiagramType type) {
if (skinParam.useSwimlanes(type))
return "sinkIn" + cluster.getColor();
return null;
}
private String empty() {
// return "empty" + color;
// We use the same node with one for thereALinkFromOrToGroup2 as an empty
// because we cannot put a new node in the nested inside of the cluster
// if thereALinkFromOrToGroup2 is enabled.
return Cluster.getSpecialPointId(cluster.getGroup());
}
private boolean hasPort() {
for (EntityPosition pos : entityPositionsExceptNormal())
if (pos.isPort())
return true;
return false;
}
private Set<EntityPosition> entityPositionsExceptNormal() {
final Set<EntityPosition> result = EnumSet.<EntityPosition>noneOf(EntityPosition.class);
for (SvekNode sh : cluster.getNodes())
if (sh.getEntityPosition() != EntityPosition.NORMAL)
result.add(sh.getEntityPosition());
return Collections.unmodifiableSet(result);
}
private void subgraphClusterNoLabel(StringBuilder sb, String id) {
subgraphClusterWithLabel(sb, id, "\"\"");
}
private void subgraphClusterWithLabel(StringBuilder sb, String id, String label) {
sb.append("subgraph " + cluster.getClusterId() + id + " {");
sb.append("label=" + label + ";");
}
// private void printClusterEntryExit(StringBuilder sb, StringBounder stringBounder) {
// printRanks(Cluster.RANK_SOURCE, withPosition(EntityPosition.getInputs()), sb, stringBounder);
// // printRanks(Cluster.RANK_SAME, withPosition(EntityPosition.getSame()), sb,
// // stringBounder);
// printRanks(Cluster.RANK_SINK, withPosition(EntityPosition.getOutputs()), sb, stringBounder);
// }
private void printRanks(String rank, List<? extends SvekNode> entries, StringBuilder sb,
StringBounder stringBounder) {
if (entries.size() > 0) {
sb.append("{rank=" + rank + ";");
for (SvekNode sh1 : entries)
sb.append(sh1.getUid() + ";");
sb.append("}");
SvekUtils.println(sb);
for (SvekNode sh2 : entries)
sh2.appendShape(sb, stringBounder);
SvekUtils.println(sb);
}
}
// private List<SvekNode> withPosition(Set<EntityPosition> positions) {
// final List<SvekNode> result = new ArrayList<>();
// for (final Iterator<SvekNode> it = cluster.getNodes().iterator(); it.hasNext();) {
// final SvekNode sh = it.next();
// if (positions.contains(sh.getEntityPosition()))
// result.add(sh);
//
// }
// return result;
// }
private boolean protection0(UmlDiagramType type) {
if (skinParam.useSwimlanes(type))
return false;
return true;
}
private boolean protection1(UmlDiagramType type) {
if (cluster.getGroup().getUSymbol() == USymbols.NODE)
return true;
if (skinParam.useSwimlanes(type))
return false;
return true;
}
private boolean isThereALinkFromOrToGroup(Collection<SvekLine> lines) {
for (SvekLine line : lines)
if (line.isLinkFromOrTo(cluster.getGroup()))
return true;
return false;
}
}

View File

@ -42,14 +42,13 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.BaseFile;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.cucadiagram.CucaDiagram;
@ -74,8 +73,6 @@ public class DotStringFactory implements Moveable {
private final Bibliotekon bibliotekon = new Bibliotekon();
final private Set<String> rankMin = new HashSet<>();
private final ColorSequence colorSequence;
private final Cluster root;
@ -114,19 +111,6 @@ public class DotStringFactory implements Moveable {
current.addNode(node);
}
private void printMinRanking(StringBuilder sb) {
if (rankMin.size() == 0)
return;
sb.append("{ rank = min;");
for (String id : rankMin) {
sb.append(id);
sb.append(";");
}
sb.append("}");
}
private double getHorizontalDzeta() {
double max = 0;
for (SvekLine l : bibliotekon.allLines()) {
@ -146,6 +130,8 @@ public class DotStringFactory implements Moveable {
max = c;
}
if (OptionFlags.USE_KERMOR)
return max / 100;
return max / 10;
}
@ -211,16 +197,28 @@ public class DotStringFactory implements Moveable {
manageMinMaxCluster(sb);
root.printCluster1(sb, bibliotekon.allLines(), stringBounder);
for (SvekLine line : bibliotekon.lines0())
line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines);
if (OptionFlags.USE_KERMOR) {
for (SvekLine line : bibliotekon.lines0())
line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines);
for (SvekLine line : bibliotekon.lines1())
line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines);
root.fillRankMin(rankMin);
root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(), umlDiagramType);
printMinRanking(sb);
root.printCluster3_forKermor(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(),
umlDiagramType);
for (SvekLine line : bibliotekon.lines1())
line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines);
} else {
root.printCluster1(sb, bibliotekon.allLines(), stringBounder);
for (SvekLine line : bibliotekon.lines0())
line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines);
root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(),
umlDiagramType);
for (SvekLine line : bibliotekon.lines1())
line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines);
}
SvekUtils.println(sb);
sb.append("}");
@ -268,6 +266,8 @@ public class DotStringFactory implements Moveable {
// return 29;
return 40;
}
if (OptionFlags.USE_KERMOR)
return 40;
return 60;
}
@ -370,11 +370,8 @@ public class DotStringFactory implements Moveable {
|| node.getType() == ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE || node.getType() == ShapeType.FOLDER
|| node.getType() == ShapeType.DIAMOND || node.getType() == ShapeType.RECTANGLE_PORT) {
final List<Point2D.Double> points = svgResult.substring(idx).extractList(SvgResult.POINTS_EQUALS);
final double minY = SvekUtils.getMinY(points);
final double overscanX = node.getOverscanX(stringBounder);
final double minX = SvekUtils.getMinX(points);
// corner1.manage(minX - overscanX, minY);
node.moveSvek(minX, minY);
final Point2D min = SvekUtils.getMinXY(points);
node.moveSvek(min.getX(), min.getY());
} else if (node.getType() == ShapeType.ROUND_RECTANGLE) {
final int idx2 = svg.indexOf("d=\"", idx + 1);
idx = svg.indexOf("points=\"", idx + 1);
@ -389,19 +386,16 @@ public class DotStringFactory implements Moveable {
points.addAll(svgResult.substring(idx).extractList(SvgResult.POINTS_EQUALS));
}
}
final double minX = SvekUtils.getMinX(points);
final double minY = SvekUtils.getMinY(points);
// corner1.manage(minX, minY);
node.moveSvek(minX, minY);
final Point2D min = SvekUtils.getMinXY(points);
node.moveSvek(min.getX(), min.getY());
} else if (node.getType() == ShapeType.OCTAGON || node.getType() == ShapeType.HEXAGON) {
idx = svg.indexOf("points=\"", idx + 1);
final int starting = idx;
final List<Point2D.Double> points = svgResult.substring(starting).extractList(SvgResult.POINTS_EQUALS);
final double minX = SvekUtils.getMinX(points);
final double minY = SvekUtils.getMinY(points);
final Point2D min = SvekUtils.getMinXY(points);
// corner1.manage(minX, minY);
node.moveSvek(minX, minY);
node.setPolygon(minX, minY, points);
node.moveSvek(min.getX(), min.getY());
node.setPolygon(min.getX(), min.getY(), points);
} else if (node.getType() == ShapeType.CIRCLE || node.getType() == ShapeType.OVAL) {
final double cx = SvekUtils.getValue(svg, idx, "cx");
final double cy = SvekUtils.getValue(svg, idx, "cy") + fullHeight;
@ -423,23 +417,24 @@ public class DotStringFactory implements Moveable {
int idx = getClusterIndex(svg, cluster.getColor());
final int starting = idx;
final List<Point2D.Double> points = svgResult.substring(starting).extractList(SvgResult.POINTS_EQUALS);
final double minX = SvekUtils.getMinX(points);
final double minY = SvekUtils.getMinY(points);
final double maxX = SvekUtils.getMaxX(points);
final double maxY = SvekUtils.getMaxY(points);
cluster.setPosition(minX, minY, maxX, maxY);
// corner1.manage(minX, minY);
final Point2D min = SvekUtils.getMinXY(points);
final Point2D max = SvekUtils.getMaxXY(points);
cluster.setPosition(min, max);
if (cluster.getTitleAndAttributeWidth() == 0 || cluster.getTitleAndAttributeHeight() == 0)
continue;
idx = getClusterIndex(svg, cluster.getTitleColor());
final int starting1 = idx;
final List<Point2D.Double> pointsTitle = svgResult.substring(starting1)
.extractList(SvgResult.POINTS_EQUALS);
final double minXtitle = SvekUtils.getMinX(pointsTitle);
final double minYtitle = SvekUtils.getMinY(pointsTitle);
cluster.setTitlePosition(minXtitle, minYtitle);
final List<Point2D.Double> pointsTitle = svgResult.substring(idx).extractList(SvgResult.POINTS_EQUALS);
cluster.setTitlePosition(SvekUtils.getMinXY(pointsTitle));
if (OptionFlags.USE_KERMOR) {
if (cluster.getGroup().getNotes().size() > 0) {
idx = getClusterIndex(svg, cluster.getColorNoteUp());
final List<Point2D.Double> noteUp = svgResult.substring(idx).extractList(SvgResult.POINTS_EQUALS);
cluster.setNoteUpPosition(SvekUtils.getMinXY(noteUp));
}
}
}
for (SvekLine line : bibliotekon.allLines())

View File

@ -59,6 +59,7 @@ import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.awt.geom.Dimension2D;
import net.sourceforge.plantuml.command.Position;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.CucaNote;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.EntityPort;
import net.sourceforge.plantuml.cucadiagram.IEntity;
@ -285,25 +286,26 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
}
final TextBlock noteOnly;
if (link.getNote() == null) {
noteOnly = TextBlockUtils.EMPTY_TEXT_BLOCK;
final CucaNote note = link.getNote();
if (note == null) {
labelText = labelOnly;
} else {
noteOnly = new EntityImageNoteLink(link.getNote(), link.getNoteColors(), skinParam, link.getStyleBuilder());
if (link.getNoteLinkStrategy() == NoteLinkStrategy.HALF_NOT_PRINTED
|| link.getNoteLinkStrategy() == NoteLinkStrategy.HALF_PRINTED_FULL)
final TextBlock noteOnly = new EntityImageNoteLink(note.getDisplay(), note.getColors(), skinParam,
link.getStyleBuilder());
if (note.getStrategy() == NoteLinkStrategy.HALF_NOT_PRINTED
|| note.getStrategy() == NoteLinkStrategy.HALF_PRINTED_FULL)
divideLabelWidthByTwo = true;
}
if (note.getPosition() == Position.LEFT)
labelText = TextBlockUtils.mergeLR(noteOnly, labelOnly, VerticalAlignment.CENTER);
else if (note.getPosition() == Position.RIGHT)
labelText = TextBlockUtils.mergeLR(labelOnly, noteOnly, VerticalAlignment.CENTER);
else if (note.getPosition() == Position.TOP)
labelText = TextBlockUtils.mergeTB(noteOnly, labelOnly, HorizontalAlignment.CENTER);
else
labelText = TextBlockUtils.mergeTB(labelOnly, noteOnly, HorizontalAlignment.CENTER);
if (link.getNotePosition() == Position.LEFT)
labelText = TextBlockUtils.mergeLR(noteOnly, labelOnly, VerticalAlignment.CENTER);
else if (link.getNotePosition() == Position.RIGHT)
labelText = TextBlockUtils.mergeLR(labelOnly, noteOnly, VerticalAlignment.CENTER);
else if (link.getNotePosition() == Position.TOP)
labelText = TextBlockUtils.mergeTB(noteOnly, labelOnly, HorizontalAlignment.CENTER);
else
labelText = TextBlockUtils.mergeTB(labelOnly, noteOnly, HorizontalAlignment.CENTER);
}
if (link.getQualifier1() == null)
startTailText = null;
@ -632,7 +634,7 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
return dotPath.getBeziers().size() <= 1;
}
private Point2D.Double getXY(SvgResult svgResult, int color) {
private Point2D getXY(SvgResult svgResult, int color) {
final int idx = svgResult.getIndexFromColor(color);
if (idx == -1)
return null;
@ -730,7 +732,7 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
ug = ug.apply(new UStroke()).apply(color);
if (hasNoteLabelText() && this.labelXY != null
&& link.getNoteLinkStrategy() != NoteLinkStrategy.HALF_NOT_PRINTED)
&& (link.getNote() == null || link.getNote().getStrategy() != NoteLinkStrategy.HALF_NOT_PRINTED))
this.labelText.drawU(ug.apply(new UTranslate(x + this.labelXY.getPosition().getX() + labelShield,
y + this.labelXY.getPosition().getY() + labelShield)));

View File

@ -78,8 +78,6 @@ public class SvekNode implements Positionable, Hideable {
private Cluster cluster;
private final boolean top;
public final Cluster getCluster() {
return cluster;
}
@ -100,7 +98,6 @@ public class SvekNode implements Positionable, Hideable {
this.stringBounder = stringBounder;
this.entityPosition = ent.getEntityPosition();
this.image = image;
this.top = ent.isTop();
this.type = image.getShapeType();
this.color = colorSequence.getValue();
@ -136,18 +133,22 @@ public class SvekNode implements Positionable, Hideable {
public void appendShape(StringBuilder sb, StringBounder stringBounder) {
if (type == ShapeType.RECTANGLE_HTML_FOR_PORTS) {
appendLabelHtmlSpecialForLink(sb, stringBounder);
SvekUtils.println(sb);
return;
}
if (type == ShapeType.RECTANGLE_PORT) {
appendLabelHtmlSpecialForPort(sb, stringBounder);
SvekUtils.println(sb);
return;
}
if (type == ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE) {
appendHtml(sb);
SvekUtils.println(sb);
return;
}
if (type == ShapeType.RECTANGLE && shield().isZero() == false) {
appendHtml(sb);
SvekUtils.println(sb);
return;
}
sb.append(uid);
@ -362,10 +363,6 @@ public class SvekNode implements Positionable, Hideable {
return image;
}
public final boolean isTop() {
return top;
}
public Point2D getPosition() {
return new Point2D.Double(minX, minY);
}

View File

@ -65,48 +65,29 @@ public class SvekUtils {
}
public static double getMaxX(List<Point2D.Double> points) {
double result = points.get(0).x;
public static Point2D getMinXY(List<Point2D.Double> points) {
double minx = points.get(0).x;
double miny = points.get(0).y;
for (int i = 1; i < points.size(); i++) {
if (points.get(i).x > result) {
result = points.get(i).x;
}
if (points.get(i).x < minx)
minx = points.get(i).x;
if (points.get(i).y < miny)
miny = points.get(i).y;
}
return result;
return new Point2D.Double(minx, miny);
}
public static double getMinX(List<Point2D.Double> points) {
double result = points.get(0).x;
public static Point2D getMaxXY(List<Point2D.Double> points) {
double maxx = points.get(0).x;
double maxy = points.get(0).y;
for (int i = 1; i < points.size(); i++) {
if (points.get(i).x < result) {
result = points.get(i).x;
}
if (points.get(i).x > maxx)
maxx = points.get(i).x;
if (points.get(i).y > maxy)
maxy = points.get(i).y;
}
return result;
}
public static Point2D.Double getMinXY(List<Point2D.Double> points) {
return new Point2D.Double(getMinX(points), getMinY(points));
}
public static double getMaxY(List<Point2D.Double> points) {
double result = points.get(0).y;
for (int i = 1; i < points.size(); i++) {
if (points.get(i).y > result) {
result = points.get(i).y;
}
}
return result;
}
public static double getMinY(List<Point2D.Double> points) {
double result = points.get(0).y;
for (int i = 1; i < points.size(); i++) {
if (points.get(i).y < result) {
result = points.get(i).y;
}
}
return result;
return new Point2D.Double(maxx, maxy);
}
public static void println(StringBuilder sb) {

View File

@ -49,6 +49,7 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@ -119,15 +120,33 @@ public class ScxmlStateDiagramStandard {
}
private Element createState(IEntity entity) {
final LeafType type = entity.getLeafType();
final Element state = document.createElement("state");
state.setAttribute("id", getId(entity));
final Stereotype stereotype = entity.getStereotype();
if (stereotype != null) {
state.setAttribute("stereotype", stereotype.getLabels(Guillemet.NONE).get(0));
if (type == LeafType.NOTE) {
state.setAttribute("stereotype", "note");
state.setAttribute("id", entity.getCode().getName());
final Display display = entity.getDisplay();
final StringBuilder sb = new StringBuilder();
for (CharSequence s : display) {
sb.append(s);
sb.append("\n");
}
if (sb.length() > 0)
sb.setLength(sb.length() - 1);
final Comment comment = document.createComment(sb.toString());
state.appendChild(comment);
} else {
state.setAttribute("id", getId(entity));
final Stereotype stereotype = entity.getStereotype();
if (stereotype != null)
state.setAttribute("stereotype", stereotype.getLabels(Guillemet.NONE).get(0));
for (final Link link : diagram.getLinks())
if (link.getEntity1() == entity)
addLink(state, link);
}
for (final Link link : diagram.getLinks())
if (link.getEntity1() == entity)
addLink(state, link);
return state;
}

View File

@ -0,0 +1,49 @@
package nonreg.scxml;
import java.io.IOException;
import org.junit.jupiter.api.Test;
/*
https://github.com/plantuml/plantuml/issues/1111
Test diagram MUST be put between triple quotes
"""
@startuml
state module {
}
note as PARAMETERS
localparam MAX_VAL 10
parameter COUNT_WIDTH 4
end note
@enduml
"""
Expected result MUST be put between triple brackets
{{{
<?xml version="1.0" encoding="UTF-8"?><scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0">
<state id="PARAMETERS" stereotype="note">
<!--localparam MAX_VAL 10
parameter COUNT_WIDTH 4-->
</state>
<state id="module"/>
</scxml>
}}}
*/
public class SCXML0005_Test extends ScXmlTest {
@Test
void testSimple() throws IOException {
checkXmlAndDescription("(1 entities)");
}
}