mirror of
https://github.com/octoleo/plantuml.git
synced 2024-12-22 02:49:06 +00:00
Scxml improvement
This commit is contained in:
parent
a562d24aa4
commit
847f482609
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
79
src/net/sourceforge/plantuml/cucadiagram/CucaNote.java
Normal file
79
src/net/sourceforge/plantuml/cucadiagram/CucaNote.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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() {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
267
src/net/sourceforge/plantuml/svek/ClusterDotStringKermor.java
Normal file
267
src/net/sourceforge/plantuml/svek/ClusterDotStringKermor.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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,17 +197,29 @@ public class DotStringFactory implements Moveable {
|
||||
|
||||
manageMinMaxCluster(sb);
|
||||
|
||||
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.printCluster3_forKermor(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(),
|
||||
umlDiagramType);
|
||||
|
||||
} else {
|
||||
root.printCluster1(sb, bibliotekon.allLines(), stringBounder);
|
||||
|
||||
for (SvekLine line : bibliotekon.lines0())
|
||||
line.appendLine(getGraphvizVersion(), sb, dotMode, dotSplines);
|
||||
|
||||
root.fillRankMin(rankMin);
|
||||
root.printCluster2(sb, bibliotekon.allLines(), stringBounder, dotMode, getGraphvizVersion(), umlDiagramType);
|
||||
printMinRanking(sb);
|
||||
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())
|
||||
|
@ -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,26 +286,27 @@ 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 (link.getNotePosition() == Position.LEFT)
|
||||
if (note.getPosition() == Position.LEFT)
|
||||
labelText = TextBlockUtils.mergeLR(noteOnly, labelOnly, VerticalAlignment.CENTER);
|
||||
else if (link.getNotePosition() == Position.RIGHT)
|
||||
else if (note.getPosition() == Position.RIGHT)
|
||||
labelText = TextBlockUtils.mergeLR(labelOnly, noteOnly, VerticalAlignment.CENTER);
|
||||
else if (link.getNotePosition() == Position.TOP)
|
||||
else if (note.getPosition() == Position.TOP)
|
||||
labelText = TextBlockUtils.mergeTB(noteOnly, labelOnly, HorizontalAlignment.CENTER);
|
||||
else
|
||||
labelText = TextBlockUtils.mergeTB(labelOnly, noteOnly, HorizontalAlignment.CENTER);
|
||||
|
||||
}
|
||||
|
||||
if (link.getQualifier1() == null)
|
||||
startTailText = null;
|
||||
else
|
||||
@ -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)));
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
if (points.get(i).x > maxx)
|
||||
maxx = points.get(i).x;
|
||||
if (points.get(i).y > maxy)
|
||||
maxy = points.get(i).y;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -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");
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
49
test/nonreg/scxml/SCXML0005_Test.java
Normal file
49
test/nonreg/scxml/SCXML0005_Test.java
Normal 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)");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user