1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-09-27 14:39:02 +00:00

Merge pull request #925 from blipper/master

Preserve element group structure in svg output to allow more intelligent post-processing
This commit is contained in:
PlantUML 2022-02-15 19:37:27 +01:00 committed by GitHub
commit 7fca076240
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 168 additions and 112 deletions

View File

@ -45,6 +45,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColor;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Map;
public abstract class UGraphicDelegator implements UGraphic { public abstract class UGraphicDelegator implements UGraphic {
@ -89,8 +90,8 @@ public abstract class UGraphicDelegator implements UGraphic {
ug.closeUrl(); ug.closeUrl();
} }
public void startGroup(UGroupType type, String ident) { public void startGroup(Map<UGroupType, String> typeIdents) {
ug.startGroup(type, ident); ug.startGroup(typeIdents);
} }
public void closeGroup() { public void closeGroup() {

View File

@ -80,6 +80,7 @@ import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.svek.image.EntityImageState; import net.sourceforge.plantuml.svek.image.EntityImageState;
import net.sourceforge.plantuml.ugraphic.UComment; import net.sourceforge.plantuml.ugraphic.UComment;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGroupType;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UStroke;
@ -347,6 +348,9 @@ public class Cluster implements Moveable {
} }
ug.startGroup(Collections.singletonMap(UGroupType.ID, "cluster_" + fullName));
final Url url = group.getUrl99(); final Url url = group.getUrl99();
if (url != null) if (url != null)
ug.startUrl(url); ug.startUrl(url);
@ -411,8 +415,8 @@ public class Cluster implements Moveable {
} finally { } finally {
if (url != null) if (url != null)
ug.closeUrl(); ug.closeUrl();
ug.closeGroup();
} }
} }
static public UStroke getStrokeInternal(IGroup group, ISkinParam skinParam, Style style) { static public UStroke getStrokeInternal(IGroup group, ISkinParam skinParam, Style style) {

View File

@ -37,11 +37,7 @@ package net.sourceforge.plantuml.svek;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import net.sourceforge.plantuml.AlignmentParam; import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ColorParam;
@ -623,8 +619,10 @@ public class SvekLine implements Moveable, Hideable, GuideLine {
return; return;
ug.draw(link.commentForSvg()); ug.draw(link.commentForSvg());
ug.startGroup(UGroupType.CLASS, Map<UGroupType, String> typeIDent = new HashMap<>();
"link " + link.getEntity1().getCode() + " " + link.getEntity2().getCode() + " selected"); typeIDent.put(UGroupType.CLASS, "link " + link.getEntity1().getCode() + " " + link.getEntity2().getCode() + " selected");
typeIDent.put(UGroupType.ID, "link_" + link.getEntity1().getCode() + "_" + link.getEntity2().getCode());
ug.startGroup(typeIDent);
double x = 0; double x = 0;
double y = 0; double y = 0;
final Url url = link.getUrl(); final Url url = link.getUrl();

View File

@ -36,6 +36,9 @@
package net.sourceforge.plantuml.svek.image; package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Dimension2DDouble;
@ -101,8 +104,10 @@ public class EntityImageBranch extends AbstractEntityImage {
} }
diams.setDeltaShadow(shadowing); diams.setDeltaShadow(shadowing);
Map<UGroupType, String> typeIDent = new HashMap<>();
ug.startGroup(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected"); typeIDent.put(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected");
typeIDent.put(UGroupType.ID, "elem_" + getEntity().getCode());
ug.startGroup(typeIDent);
ug.apply(border).apply(back.bg()).apply(stroke).draw(diams); ug.apply(border).apply(back.bg()).apply(stroke).draw(diams);
ug.closeGroup(); ug.closeGroup();
} }

View File

@ -37,6 +37,9 @@ package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.CornerParam; import net.sourceforge.plantuml.CornerParam;
@ -135,7 +138,10 @@ public class EntityImageClass extends AbstractEntityImage implements Stencil, Wi
if (url != null) if (url != null)
ug.startUrl(url); ug.startUrl(url);
ug.startGroup(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected"); Map<UGroupType, String> typeIDent = new HashMap<>();
typeIDent.put(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected");
typeIDent.put(UGroupType.ID, "elem_" + getEntity().getCode());
ug.startGroup(typeIDent);
drawInternal(ug); drawInternal(ug);
ug.closeGroup(); ug.closeGroup();

View File

@ -37,10 +37,7 @@
package net.sourceforge.plantuml.svek.image; package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.util.Collection; import java.util.*;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.Guillemet;
@ -286,7 +283,10 @@ public class EntityImageDescription extends AbstractEntityImage {
final public void drawU(UGraphic ug) { final public void drawU(UGraphic ug) {
ug.draw(new UComment("entity " + getEntity().getCodeGetName())); ug.draw(new UComment("entity " + getEntity().getCodeGetName()));
ug.startGroup(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected"); Map<UGroupType, String> typeIDent = new HashMap<>();
typeIDent.put(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected");
typeIDent.put(UGroupType.ID, "elem_" + getEntity().getCode());
ug.startGroup(typeIDent);
if (url != null) if (url != null)
ug.startUrl(url); ug.startUrl(url);

View File

@ -36,6 +36,9 @@
package net.sourceforge.plantuml.svek.image; package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Dimension2DDouble;
@ -131,7 +134,10 @@ public class EntityImageLollipopInterface extends AbstractEntityImage {
if (url != null) if (url != null)
ug.startUrl(url); ug.startUrl(url);
ug.startGroup(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected"); Map<UGroupType, String> typeIDent = new HashMap<>();
typeIDent.put(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected");
typeIDent.put(UGroupType.ID, "elem_" + getEntity().getCode());
ug.startGroup(typeIDent);
ug.apply(getUStroke()).draw(circle); ug.apply(getUStroke()).draw(circle);
ug.closeGroup(); ug.closeGroup();

View File

@ -36,6 +36,9 @@
package net.sourceforge.plantuml.svek.image; package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.CornerParam; import net.sourceforge.plantuml.CornerParam;
@ -193,7 +196,10 @@ public class EntityImageMap extends AbstractEntityImage implements Stencil, With
if (url != null) if (url != null)
ug.startUrl(url); ug.startUrl(url);
ug.startGroup(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected"); Map<UGroupType, String> typeIDent = new HashMap<>();
typeIDent.put(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected");
typeIDent.put(UGroupType.ID, "elem_" + getEntity().getCode());
ug.startGroup(typeIDent);
ug.apply(stroke).draw(rect); ug.apply(stroke).draw(rect);
final ULayoutGroup header = new ULayoutGroup(new PlacementStrategyY1Y2(ug.getStringBounder())); final ULayoutGroup header = new ULayoutGroup(new PlacementStrategyY1Y2(ug.getStringBounder()));

View File

@ -38,6 +38,9 @@ package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.awt.geom.Line2D; import java.awt.geom.Line2D;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import net.sourceforge.plantuml.AlignmentParam; import net.sourceforge.plantuml.AlignmentParam;
@ -217,7 +220,10 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil {
final public void drawU(UGraphic ug) { final public void drawU(UGraphic ug) {
final Url url = getEntity().getUrl99(); final Url url = getEntity().getUrl99();
ug.startGroup(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected"); Map<UGroupType, String> typeIDent = new HashMap<>();
typeIDent.put(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected");
typeIDent.put(UGroupType.ID, "elem_" + getEntity().getCode());
ug.startGroup(typeIDent);
if (url != null) if (url != null)
ug.startUrl(url); ug.startUrl(url);

View File

@ -36,6 +36,9 @@
package net.sourceforge.plantuml.svek.image; package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.CornerParam; import net.sourceforge.plantuml.CornerParam;
@ -195,7 +198,11 @@ public class EntityImageObject extends AbstractEntityImage implements Stencil, W
if (url != null) if (url != null)
ug.startUrl(url); ug.startUrl(url);
ug.startGroup(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected");
Map<UGroupType, String> typeIDent = new HashMap<>();
typeIDent.put(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected");
typeIDent.put(UGroupType.ID, "elem_" + getEntity().getCode());
ug.startGroup(typeIDent);
ug.apply(stroke).draw(rect); ug.apply(stroke).draw(rect);
final ULayoutGroup header = new ULayoutGroup(new PlacementStrategyY1Y2(ug.getStringBounder())); final ULayoutGroup header = new ULayoutGroup(new PlacementStrategyY1Y2(ug.getStringBounder()));

View File

@ -36,6 +36,7 @@
package net.sourceforge.plantuml.svek.image; package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.util.Collections;
import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.FontParam;
@ -102,7 +103,7 @@ public class EntityImageState extends EntityImageStateCommon {
} }
final public void drawU(UGraphic ug) { final public void drawU(UGraphic ug) {
ug.startGroup(UGroupType.ID, getEntity().getIdent().toString(".")); ug.startGroup(Collections.singletonMap(UGroupType.ID, getEntity().getIdent().toString(".")));
if (url != null) if (url != null)
ug.startUrl(url); ug.startUrl(url);

View File

@ -37,6 +37,9 @@ package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.FontParam;
@ -159,7 +162,10 @@ public class EntityImageUseCase extends AbstractEntityImage {
ug = ug.apply(backcolor.bg()); ug = ug.apply(backcolor.bg());
final UGraphic ug2 = new MyUGraphicEllipse(ug, 0, 0, ellipse.getUEllipse()); final UGraphic ug2 = new MyUGraphicEllipse(ug, 0, 0, ellipse.getUEllipse());
ug2.startGroup(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected"); Map<UGroupType, String> typeIDent = new HashMap<>();
typeIDent.put(UGroupType.CLASS, "elem " + getEntity().getCode() + " selected");
typeIDent.put(UGroupType.ID, "elem_" + getEntity().getCode());
ug.startGroup(typeIDent);
ellipse.drawU(ug2); ellipse.drawU(ug2);
ug2.closeGroup(); ug2.closeGroup();

View File

@ -992,9 +992,11 @@ public class SvgGraphics {
// javascript: security issue // javascript: security issue
if (SecurityUtils.ignoreThisLink(url)) if (SecurityUtils.ignoreThisLink(url))
return; return;
Log.info("openLink=" + title);
if (pendingAction.size() > 0)
closeLink(); // if (pendingAction.size() > 0)
// closeLink();
pendingAction.add(0, (Element) document.createElement("a")); pendingAction.add(0, (Element) document.createElement("a"));
pendingAction.get(0).setAttribute("target", target); pendingAction.get(0).setAttribute("target", target);
@ -1039,13 +1041,18 @@ public class SvgGraphics {
} }
} }
public void startGroup(UGroupType type, String ident) { public void startGroup(Map<UGroupType, String> typeIdents) {
if (type == UGroupType.ID) { Log.debug("startGroup=" + typeIdents) ;
if (!typeIdents.isEmpty())
pendingAction.add(0, (Element) document.createElement("g")); pendingAction.add(0, (Element) document.createElement("g"));
pendingAction.get(0).setAttribute("id", ident); for (Map.Entry<UGroupType, String> typeIdent : typeIdents.entrySet()) {
} else if (INTERACTIVE && type == UGroupType.CLASS) { if (typeIdent.getKey() == UGroupType.ID) {
pendingAction.add(0, (Element) document.createElement("g")); pendingAction.get(0).setAttribute("id", typeIdent.getValue());
pendingAction.get(0).setAttribute("class", ident); }
if (INTERACTIVE && typeIdent.getKey() == UGroupType.CLASS) {
pendingAction.get(0).setAttribute("class", typeIdent.getValue());
}
} }
} }

View File

@ -35,6 +35,7 @@
*/ */
package net.sourceforge.plantuml.ugraphic; package net.sourceforge.plantuml.ugraphic;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.Url;
@ -181,7 +182,7 @@ public abstract class AbstractCommonUGraphic implements UGraphic {
public void closeUrl() { public void closeUrl() {
} }
public void startGroup(UGroupType type, String ident) { public void startGroup(Map<UGroupType, String> typeIdents) {
} }
public void closeGroup() { public void closeGroup() {

View File

@ -42,6 +42,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColor;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Map;
public interface UGraphic { public interface UGraphic {
@ -59,7 +60,7 @@ public interface UGraphic {
public void closeUrl(); public void closeUrl();
public void startGroup(UGroupType type, String ident); public void startGroup(Map<UGroupType, String> typeIdents);
public void closeGroup(); public void closeGroup();

View File

@ -43,6 +43,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Map;
public abstract class UGraphicNo implements UGraphic { public abstract class UGraphicNo implements UGraphic {
@ -68,7 +69,7 @@ public abstract class UGraphicNo implements UGraphic {
} }
@Override @Override
public void startGroup(UGroupType type, String ident) { public void startGroup(Map<UGroupType, String> typeIdents) {
} }
@Override @Override

View File

@ -37,5 +37,4 @@ package net.sourceforge.plantuml.ugraphic;
public enum UGroupType { public enum UGroupType {
ID, CLASS ID, CLASS
} }

View File

@ -37,6 +37,7 @@ package net.sourceforge.plantuml.ugraphic.svg;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Map;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
@ -157,8 +158,8 @@ public class UGraphicSvg extends AbstractUGraphic<SvgGraphics> implements ClipCo
} }
@Override @Override
public void startGroup(UGroupType type, String ident) { public void startGroup(Map<UGroupType, String> typeIdents) {
getGraphicObject().startGroup(type, ident); getGraphicObject().startGroup(typeIdents);
} }
@Override @Override