Skip to content
Snippets Groups Projects
Commit 788e5bb1 authored by Andrea Burattin's avatar Andrea Burattin
Browse files

Initial prototype of the system

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 873 additions and 0 deletions
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
/target/
.project 0 → 100644
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>framework</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=11
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
pom.xml 0 → 100644
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>beamline</groupId>
<artifactId>framework</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>ApromoreCore_SupportLibs</id>
<name>Maven repository for JARs specific to the Apromore project</name>
<url>https://raw.github.com/apromore/ApromoreCore_SupportLibs/master/mvn-repo/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
<dependency>
<groupId>org.deckfour</groupId>
<artifactId>openxes</artifactId>
<version>2.16</version>
</dependency>
<dependency>
<groupId>org.deckfour</groupId>
<artifactId>spex</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>beamline</groupId>
<artifactId>graphviz</artifactId>
<version>0.0.2</version>
</dependency>
<dependency>
<groupId>io.reactivex.rxjava3</groupId>
<artifactId>rxjava</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package beamline.models.algorithms;
import java.util.Iterator;
import beamline.models.responses.Response;
import beamline.models.streams.ObservableStream;
public abstract class StreamMiningAlgorithm<T, K extends Response> implements ObservableStream<K> {
private int processedEvents = 0;
private K latestResponse;
protected abstract K ingest(T event);
public K process(T event) {
this.processedEvents++;
latestResponse = ingest(event);
return latestResponse;
}
public int getProcessedEvents() {
return processedEvents;
}
public K getLatestResponse() {
return latestResponse;
}
protected K setLatestResponse(K latestResponse) {
this.latestResponse = latestResponse;
return latestResponse;
}
@Override
public void prepare() throws Exception { }
@Override
public Iterator<K> iterator() {
return null;
}
}
package beamline.models.filters;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Stream;
import org.deckfour.xes.model.XTrace;
public class EventNameFilterKeepOnly extends XesFilter {
private Set<String> activityNamesToKeep;
public EventNameFilterKeepOnly(String ...activityNamesToKeep) {
this.activityNamesToKeep = new HashSet<String>(Arrays.asList(activityNamesToKeep));
}
@Override
public Iterator<XTrace> iterator() {
return null;
}
@Override
public Stream<XTrace> stream() {
// TODO Auto-generated method stub
return null;
}
}
package beamline.models.filters;
import beamline.models.streams.XesSource;
public abstract class XesFilter implements XesSource {
@Override
public void prepare() throws Exception { }
}
package beamline.models.responses;
import beamline.graphviz.Dot;
public interface GraphvizResponse extends Response {
public abstract Dot generateDot();
}
package beamline.models.responses;
public interface Response {
}
package beamline.models.streams;
import java.util.Iterator;
import java.util.stream.Stream;
public interface ObservableStream<T> extends Iterable<T> {
public abstract void prepare() throws Exception;
public abstract Stream<T> stream();
}
package beamline.models.streams;
import java.util.Date;
import java.util.Iterator;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.deckfour.xes.extension.std.XConceptExtension;
import org.deckfour.xes.extension.std.XTimeExtension;
import org.deckfour.xes.factory.XFactory;
import org.deckfour.xes.factory.XFactoryNaiveImpl;
import org.deckfour.xes.model.XEvent;
import org.deckfour.xes.model.XTrace;
import org.eclipse.paho.client.mqttv3.IMqttClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
public class XesMqttSource implements XesSource {
private static XFactory xesFactory = new XFactoryNaiveImpl();
private String processName;
private String brokerHost;
private String topicBase;
private BlockingQueue<XTrace> queue;
private Stream<XTrace> stream;
public XesMqttSource(String brokerHost, String topicBase, String processName) {
this.brokerHost = brokerHost;
this.topicBase = topicBase;
this.processName = processName;
this.stream = Stream.generate(new Supplier<XTrace>() {
@Override
public XTrace get() {
try {
return queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
});
}
@Override
public Stream<XTrace> stream() {
return stream;
}
public void prepare() throws Exception {
this.queue = new ArrayBlockingQueue<XTrace>(1000);
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setKeepAliveInterval(30);
IMqttClient myClient = new MqttClient(brokerHost, UUID.randomUUID().toString());
myClient.setCallback(new MqttCallback() {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
int posLastSlash = topic.lastIndexOf("/");
String partBeforeActName = topic.substring(0, posLastSlash);
String activityName = topic.substring(posLastSlash + 1);
String caseId = partBeforeActName.substring(partBeforeActName.lastIndexOf("/") + 1);
XEvent event = xesFactory.createEvent();
XConceptExtension.instance().assignName(event, activityName);
XTimeExtension.instance().assignTimestamp(event, new Date());
XTrace eventWrapper = xesFactory.createTrace();
XConceptExtension.instance().assignName(eventWrapper, caseId);
eventWrapper.add(event);
queue.add(eventWrapper);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) { }
@Override
public void connectionLost(Throwable cause) { }
});
myClient.connect(options);
myClient.subscribe(topicBase + "/" + processName + "/#");
}
public Iterator<XTrace> iterator() {
return new Iterator<XTrace>() {
@Override
public boolean hasNext() {
return true;
}
@Override
public XTrace next() {
try {
return queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
};
}
}
package beamline.models.streams;
import org.deckfour.xes.model.XTrace;
public interface XesSource extends ObservableStream<XTrace> {
}
package beamline.models.streams;
import java.io.File;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Stream;
import org.deckfour.xes.extension.std.XTimeExtension;
import org.deckfour.xes.factory.XFactory;
import org.deckfour.xes.factory.XFactoryNaiveImpl;
import org.deckfour.xes.in.XParser;
import org.deckfour.xes.in.XesXmlGZIPParser;
import org.deckfour.xes.in.XesXmlParser;
import org.deckfour.xes.model.XAttributeMap;
import org.deckfour.xes.model.XEvent;
import org.deckfour.xes.model.XLog;
import org.deckfour.xes.model.XTrace;
public class XesStreamSource implements XesSource {
private static XFactory xesFactory = new XFactoryNaiveImpl();
private String fileName;
private XLog log;
private List<XTrace> events;
public XesStreamSource(String fileName) {
this.fileName = fileName;
}
public void prepare() throws Exception {
parseLog(fileName);
prepareStream();
}
public Stream<XTrace> stream() {
return events.stream();
}
public Iterator<XTrace> iterator() {
return events.iterator();
}
private void parseLog(String fileName) throws Exception {
XParser[] parsers = new XParser[] { new XesXmlGZIPParser(), new XesXmlParser() };
File file = new File(fileName);
for (XParser p : parsers) {
if (p.canParse(file)) {
log = p.parse(file).get(0);
return;
}
}
throw new Exception("XES file format not supported");
}
private void prepareStream() {
if (log == null) {
return;
}
// populate all events
events = new LinkedList<XTrace>();
for (XTrace t : log) {
for (XEvent e : t) {
// create the wrapping trace
XTrace eventWrapper = xesFactory.createTrace();
XAttributeMap am = t.getAttributes();
for (String key : am.keySet()) {
eventWrapper.getAttributes().put(key, am.get(key));
}
// create the actual event
XEvent newEvent = xesFactory.createEvent();
XAttributeMap amEvent = e.getAttributes();
for (String key : amEvent.keySet()) {
newEvent.getAttributes().put(key, amEvent.get(key));
}
eventWrapper.add(newEvent);
events.add(eventWrapper);
}
}
// sort events
Collections.sort(events, new Comparator<XTrace>() {
public int compare(XTrace o1, XTrace o2) {
XEvent e1 = o1.get(0);
XEvent e2 = o2.get(0);
Date d1 = XTimeExtension.instance().extractTimestamp(e1);
Date d2 = XTimeExtension.instance().extractTimestamp(e2);
if (d1 == null || d2 == null) {
return 0;
}
return d1.compareTo(d2);
}
});
}
}
package beamline.tester;
import java.io.File;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.deckfour.xes.extension.std.XConceptExtension;
import org.deckfour.xes.extension.std.XTimeExtension;
import org.deckfour.xes.model.XTrace;
import com.google.common.collect.Iterators;
import beamline.models.responses.GraphvizResponse;
import beamline.models.streams.XesMqttSource;
import beamline.models.streams.XesSource;
import beamline.models.streams.ObservableStream;
import beamline.models.streams.XesStreamSource;
import discovery.beamline.miners.basic.DiscoveryMiner;
public class Tester {
public static void main(String[] args) throws Exception {
System.out.println("Started");
XesSource source;
source = new XesStreamSource("C:\\Users\\andbur\\Desktop\\input-small.xes");
// source = new XesMqttSource("tcp://broker.hivemq.com:1883", "pmcep", "test");
source.prepare();
int refreshRate = 1;
DiscoveryMiner discoveryAlgorithm = new DiscoveryMiner();
discoveryAlgorithm.setMinDependency(0.3);
discoveryAlgorithm.setModelRefreshRate(refreshRate);
Stream<String> s = Arrays.asList("1234", "12", "123").stream();
s
.map(new Function<String, Integer>() {
@Override
public Integer apply(String t) {
return t.length();
}
})
.forEach(System.out::println);
// Stream<XTrace> s = source.stream();
//
// s
// .filter(new Predicate<XTrace>() {
// @Override
// public boolean test(XTrace t) {
// return "A".equals(XConceptExtension.instance().extractName(t.get(0))) ||
// "B".equals(XConceptExtension.instance().extractName(t.get(0)));
// }
// })
// .filter(new Predicate<XTrace>() {
// @Override
// public boolean test(XTrace t) {
// return "c1".equals(XConceptExtension.instance().extractName(t));
// }
// })
// .limit(2)
// .map(new Function<XTrace, String>() {
// @Override
// public String apply(XTrace t) {
// return XConceptExtension.instance().extractName(t.get(0));
// }
// })
// .forEach(System.out::println);
// .
// .forEach(new Consumer<XTrace>() {
// @Override
// public void accept(XTrace t) {
// System.out.println(
// XConceptExtension.instance().extractName(t) + " - " +
// XConceptExtension.instance().extractName(t.get(0)) + " - " +
// XTimeExtension.instance().extractTimestamp(t.get(0)));
//// discoveryAlgorithm.process(t);
// }
// });
// for(XTrace t : (Iterable<XTrace>) s::iterator) {
// System.out.println(XConceptExtension.instance().extractName(t) + " - " +
// XConceptExtension.instance().extractName(t.get(0)) + " - " +
// XTimeExtension.instance().extractTimestamp(t.get(0)));
// discoveryAlgorithm.process(eventWrapper);
// GraphvizResponse response = (GraphvizResponse) discoveryAlgorithm.getLatestResponse();
// if (discoveryAlgorithm.getProcessedEvents() % refreshRate == 0) {
//// response.generateDot().exportToSvg(new File("C:\\Users\\andbur\\Desktop\\output-" + discoveryAlgorithm.getProcessedEvents() + ".svg"));
// System.out.println("Processed " + discoveryAlgorithm.getProcessedEvents() + " events, the map has " + response.generateDot().getEdges().size() + " edges");
// }
// }
// System.out.println("Processed " + discoveryAlgorithm.getProcessedEvents() + " events, the map has " + discoveryAlgorithm.getLatestResponse().generateDot().getEdges().size() + " edges");
System.out.println("Done");
}
}
package discovery.beamline.miners.basic;
import java.util.*;
import java.util.stream.Stream;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.deckfour.xes.extension.std.XConceptExtension;
import org.deckfour.xes.model.XTrace;
import beamline.models.algorithms.StreamMiningAlgorithm;
import beamline.models.responses.Response;
public class DiscoveryMiner extends StreamMiningAlgorithm<XTrace, ProcessMap> {
private Map<String, String> latestActivityInCase = new HashMap<String, String>();
private Map<Pair<String, String>, Double> relations = new HashMap<Pair<String, String>, Double>();
private Map<String, Double> activities = new HashMap<String, Double>();
private Double maxActivityFreq = Double.MIN_VALUE;
private Double maxRelationsFreq = Double.MIN_VALUE;
private double minDependency = 1d;
private int modelRefreshRate = 0;
public void setMinDependency(double minDependency) {
this.minDependency = minDependency;
}
public void setModelRefreshRate(int modelRefreshRate) {
this.modelRefreshRate = modelRefreshRate;
}
public ProcessMap mine(double threshold) {
ProcessMap process = new ProcessMap();
for (String activity : activities.keySet()) {
process.addActivity(activity, activities.get(activity) / maxActivityFreq);
}
for (Pair<String, String> relation : relations.keySet()) {
double dependency = relations.get(relation) / maxRelationsFreq;
if (dependency >= threshold) {
process.addRelation(relation.getLeft(), relation.getRight(), dependency);
}
}
Set<String> toRemove = new HashSet<String>();
Set<String> selfLoopsToRemove = new HashSet<String>();
for (String activity : activities.keySet()) {
if (process.isStartActivity(activity) && process.isEndActivity(activity)) {
toRemove.add(activity);
}
if (process.isIsolatedNode(activity)) {
selfLoopsToRemove.add(activity);
}
}
for (String activity : toRemove) {
process.removeActivity(activity);
}
return process;
}
@Override
public ProcessMap ingest(XTrace event) {
String caseID = XConceptExtension.instance().extractName(event);
String activityName = XConceptExtension.instance().extractName(event.get(0));
Double activityFreq = 1d;
if (activities.containsKey(activityName)) {
activityFreq += activities.get(activityName);
maxActivityFreq = Math.max(maxActivityFreq, activityFreq);
}
activities.put(activityName, activityFreq);
if (latestActivityInCase.containsKey(caseID)) {
Pair<String, String> relation = new ImmutablePair<String, String>(latestActivityInCase.get(caseID), activityName);
Double relationFreq = 1d;
if (relations.containsKey(relation)) {
relationFreq += relations.get(relation);
maxRelationsFreq = Math.max(maxRelationsFreq, relationFreq);
}
relations.put(relation, relationFreq);
}
latestActivityInCase.put(caseID, activityName);
if (getProcessedEvents() % modelRefreshRate == 0) {
setLatestResponse(mine(minDependency));
}
return getLatestResponse();
}
@Override
public Stream<ProcessMap> stream() {
// TODO Auto-generated method stub
return null;
}
}
\ No newline at end of file
package discovery.beamline.miners.basic;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import beamline.graphviz.Dot;
import beamline.models.responses.GraphvizResponse;
import discovery.beamline.view.graph.PMDotModel;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class ProcessMap implements GraphvizResponse {
private Map<String, Double> activities;
private Map<Pair<String, String>, Double> relations;
@Override
public Dot generateDot() {
return new PMDotModel(this, discovery.beamline.view.graph.ColorPalette.Colors.BLUE);
}
public ProcessMap() {
this.activities = new HashMap<String, Double>();
this.relations = new HashMap<Pair<String, String>, Double>();
}
public void addActivity(String activityName, Double value) {
this.activities.put(activityName, value);
}
public void removeActivity(String activityName) {
this.activities.remove(activityName);
}
public void addRelation(String activitySource, String activityTarget, Double value) {
relations.put(new ImmutablePair<String, String>(activitySource, activityTarget), value);
}
public void removeRelation(String activitySource, String activityTarget) {
relations.remove(new ImmutablePair<String, String>(activitySource, activityTarget));
}
public Set<String> getActivities() {
return activities.keySet();
}
public Set<Pair<String, String>> getRelations() {
return relations.keySet();
}
public Double getActivityValue(String activity) {
return this.activities.get(activity);
}
public Double getRelationValue(Pair<String, String> relation) {
return this.relations.get(relation);
}
public Set<String> getIncomingActivities(String candidate) {
Set<String> result = new HashSet<String>();
for (Pair<String, String> relation : getRelations()) {
if (relation.getRight().equals(candidate)) {
result.add(relation.getLeft());
}
}
return result;
}
public Set<String> getOutgoingActivities(String candidate) {
Set<String> result = new HashSet<String>();
for (Pair<String, String> relation : getRelations()) {
if (relation.getLeft().equals(candidate)) {
result.add(relation.getRight());
}
}
return result;
}
public boolean isStartActivity(String candidate) {
return getIncomingActivities(candidate).size() == 0;
}
public boolean isEndActivity(String candidate) {
return getOutgoingActivities(candidate).size() == 0;
}
public boolean isIsolatedNode(String candidate) {
return getOutgoingActivities(candidate).equals(getIncomingActivities(candidate));
}
}
\ No newline at end of file
package discovery.beamline.view.graph;
import java.awt.Color;
// see https://content.linkedin.com/content/dam/brand/site/img/color/color-palette-order.png
public class ColorPalette {
public enum Colors {
BLUE ("#CFEDFB", "#0B4971"),
VIOLET("#F0E3EF", "#593482"),
RED ("#FFE2D2", "#98041B"),
ORANGE("#FFEBB6", "#933304"),
AQUA ("#D2ECEB", "#0E5C68"),
YELLOW("#FAF0B5", "#856A1D"),
PINK ("#FBE2ED", "#951343"),
GREEN ("#E5EFC7", "#3F652D"),
GRAY ("#E0E2E4", "#3A3C3E"),
DARK_GRAY("#86888A", "#252526");
public Color min;
public Color max;
Colors(String min, String max) {
this.min = Color.decode(min);
this.max = Color.decode(max);
}
}
public static Color getValue(Colors base, double value) {
float rMin = base.min.getRed() / 255f;
float gMin = base.min.getGreen() / 255f;
float bMin = base.min.getBlue() / 255f;
float rMax = base.max.getRed() / 255f;
float gMax = base.max.getGreen() / 255f;
float bMax = base.max.getBlue() / 255f;
float rOwn = (float) (rMin + (rMax - rMin) * value);
float gOwn = (float) (gMin + (gMax - gMin) * value);
float bOwn = (float) (bMin + (bMax - bMin) * value);
rOwn = (rOwn > 1f)? 1 : (rOwn < 0? 0 : rOwn);
gOwn = (gOwn > 1f)? 1 : (gOwn < 0? 0 : gOwn);
bOwn = (bOwn > 1f)? 1 : (bOwn < 0? 0 : bOwn);
return new Color(rOwn, gOwn, bOwn);
}
public static Color getFontColor(Color background) {
double a = 1
- (0.299 * background.getRed() + 0.587 * background.getGreen() + 0.114 * background.getBlue()) / 255;
return a < 0.5 ? Color.BLACK : Color.WHITE;
}
public static String colorToString(Color color) {
return String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue());
}
}
\ No newline at end of file
package discovery.beamline.view.graph;
import beamline.graphviz.DotEdge;
import beamline.graphviz.DotNode;
public class PMDotEdge extends DotEdge {
public PMDotEdge(DotNode source, DotNode target, String edgeText, Double weight) {
super(source, target);
setOption("decorate", "false");
setOption("fontsize", "8");
setOption("arrowsize", "0.5");
setOption("fontname", "Arial");
setOption("tailclip", "false");
if (edgeText != null) {
setLabel(" " + edgeText);
}
if (weight != null) {
setOption("color",
ColorPalette.colorToString(ColorPalette.getValue(ColorPalette.Colors.DARK_GRAY, weight)));
if ((source instanceof PMDotStartNode) || (target instanceof PMDotEndNode)) {
setOption("penwidth", "" + (1 + (5 * weight)));
} else {
setOption("penwidth", "" + (1 + (8 * weight)));
}
} else {
if ((source instanceof PMDotStartNode) || (target instanceof PMDotEndNode)) {
setOption("penwidth", "2");
} else {
setOption("penwidth", "3");
}
}
if (source instanceof PMDotStartNode) {
setOption("style", "dashed");
setOption("color", "#ACB89C");
}
if (target instanceof PMDotEndNode) {
setOption("style", "dashed");
setOption("color", "#C2B0AB");
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment