![JAR search and dependency download from the Maven repository](/logo.png)
net.sourceforge.plantuml.gitlog.SmetanaForGit Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of plantuml Show documentation
Show all versions of plantuml Show documentation
PlantUML is a component that allows to quickly write :
* sequence diagram,
* use case diagram,
* class diagram,
* activity diagram,
* component diagram,
* state diagram
* object diagram
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://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.gitlog;
import static gen.lib.cgraph.attr__c.agsafeset;
import static gen.lib.cgraph.edge__c.agedge;
import static gen.lib.cgraph.graph__c.agopen;
import static gen.lib.cgraph.node__c.agnode;
import static gen.lib.gvc.gvc__c.gvContext;
import static gen.lib.gvc.gvlayout__c.gvLayoutJobs;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import h.ST_Agedge_s;
import h.ST_Agedgeinfo_t;
import h.ST_Agnode_s;
import h.ST_Agnodeinfo_t;
import h.ST_Agraph_s;
import h.ST_GVC_s;
import net.sourceforge.plantuml.jsondiagram.Mirror;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.klimt.color.HColor;
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
import net.sourceforge.plantuml.klimt.font.StringBounder;
import net.sourceforge.plantuml.klimt.geom.XDimension2D;
import net.sourceforge.plantuml.style.ISkinParam;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import smetana.core.CString;
import smetana.core.Globals;
public class SmetanaForGit {
private final UGraphic ug;
private final ISkinParam skinParam;
private int num;
private ST_Agraph_s g;
private StringBounder stringBounder;
private final Map nodes = new LinkedHashMap();
private final List edges = new ArrayList<>();
private Mirror yMirror;
public SmetanaForGit(UGraphic ug, ISkinParam skinParam) {
this.stringBounder = ug.getStringBounder();
this.skinParam = skinParam;
this.ug = getStyle().applyStrokeAndLineColor(ug, skinParam.getIHtmlColorSet());
}
private Style getStyle() {
return StyleSignatureBasic.of(SName.root, SName.element, SName.gitDiagram)
.getMergedStyle(skinParam.getCurrentStyleBuilder());
}
private HColor arrowColor() {
return getStyle().value(PName.LineColor).asColor(skinParam.getIHtmlColorSet());
}
public void drawMe(Collection gnodes) {
initGraph(gnodes);
for (Entry ent : nodes.entrySet()) {
final ST_Agnode_s node = ent.getValue();
final UTranslate pos = getPosition(node);
final MagicBox magicBox = new MagicBox(skinParam, ent.getKey());
magicBox.drawBorder(ug.apply(pos), getSize(node));
}
for (ST_Agedge_s edge : edges) {
final ST_Agedgeinfo_t data = (ST_Agedgeinfo_t) edge.data;
new GitCurve(data, yMirror).drawCurve(arrowColor(), ug);
}
}
private XDimension2D getSize(ST_Agnode_s node) {
final ST_Agnodeinfo_t data = (ST_Agnodeinfo_t) node.data;
final double width = data.width * 72;
final double height = data.height * 72;
return new XDimension2D(width, height);
}
private UTranslate getPosition(ST_Agnode_s node) {
final ST_Agnodeinfo_t data = (ST_Agnodeinfo_t) node.data;
final double width = data.width * 72;
final double height = data.height * 72;
final double x = data.coord.x;
final double y = data.coord.y;
return new UTranslate(x - width / 2, yMirror.inv(y + height / 2));
}
private void initGraph(Collection gnodes) {
if (g != null)
return;
Globals zz = Globals.open();
try {
g = agopen(zz, new CString("g"), zz.Agdirected, null);
agsafeset(zz, g, new CString("ranksep"), new CString("0.35"), new CString(""));
for (GNode gnode : gnodes) {
final XDimension2D dim = new MagicBox(skinParam, gnode).getBigDim(stringBounder);
nodes.put(gnode, createNode(zz, dim));
}
for (GNode gnode : nodes.keySet()) {
for (GNode parent : gnode.getDowns()) {
final ST_Agedge_s edge = createEdge(zz, gnode, parent);
if (edge != null)
edges.add(edge);
}
}
final ST_GVC_s gvc = gvContext(zz);
gvLayoutJobs(zz, gvc, g);
double max = 0;
for (ST_Agnode_s node : nodes.values()) {
final ST_Agnodeinfo_t data = (ST_Agnodeinfo_t) node.data;
final double height = data.height * 72;
final double y = data.coord.y;
max = Math.max(max, y + height);
}
yMirror = new Mirror(max);
} finally {
Globals.close();
}
}
private ST_Agedge_s createEdge(Globals zz, GNode node0, GNode node1) {
final ST_Agnode_s a0 = nodes.get(node0);
final ST_Agnode_s a1 = nodes.get(node1);
if (a0 == null || a1 == null) {
return null;
}
final ST_Agedge_s edge = agedge(zz, g, a0, a1, null, true);
agsafeset(zz, edge, new CString("arrowsize"), new CString(".7"), new CString(""));
agsafeset(zz, edge, new CString("arrowtail"), new CString("none"), new CString(""));
agsafeset(zz, edge, new CString("arrowhead"), new CString("normal"), new CString(""));
return edge;
}
private ST_Agnode_s createNode(Globals zz, XDimension2D dim) {
final String width = "" + (dim.getWidth() / 72);
final String height = "" + (dim.getHeight() / 72);
final ST_Agnode_s node = agnode(zz, g, new CString("N" + num), true);
node.NAME = "N " + num;
num++;
agsafeset(zz, node, new CString("shape"), new CString("box"), new CString(""));
agsafeset(zz, node, new CString("height"), new CString("" + height), new CString(""));
agsafeset(zz, node, new CString("width"), new CString("" + width), new CString(""));
return node;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy