From 00c8fcf947d3f5c375d49a907bcefa5d8e1dd8ea Mon Sep 17 00:00:00 2001 From: nagilooh Date: Tue, 1 Aug 2023 12:41:45 +0200 Subject: Update visualization - Replace guru.nidi:graphviz-java with DOT based solution - Draws the design space as well as the model states - Design space nodes link to visualization of the sate --- .../visualization/ModelVisualizerAdapter.java | 23 ++-- .../internal/ModelVisualizerAdapterImpl.java | 120 +++++++++++---------- 2 files changed, 79 insertions(+), 64 deletions(-) (limited to 'subprojects/visualization/src/main/java/tools') diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java index 42f01242..2f71d4f3 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java @@ -1,8 +1,7 @@ package tools.refinery.visualization; -import guru.nidi.graphviz.engine.Format; -import guru.nidi.graphviz.model.MutableGraph; import tools.refinery.store.adapter.ModelAdapter; +import tools.refinery.store.tuple.Tuple; import tools.refinery.visualization.internal.FileFormat; import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl; @@ -13,21 +12,25 @@ public interface ModelVisualizerAdapter extends ModelAdapter { return new ModelVisualizerBuilderImpl(); } - public MutableGraph createVisualizationForCurrentModelState(); - - public MutableGraph createVisualizationForModelState(Long version); - public String createDotForCurrentModelState(); public String createDotForModelState(Long version); - public boolean saveVisualization(MutableGraph graph, String path); - - public boolean saveVisualization(MutableGraph graph, Format format, String path); - public boolean saveDot(String dot, String filePath); public boolean renderDot(String dot, String filePath); public boolean renderDot(String dot, FileFormat format, String filePath); + + public void addTransition(Long from, Long to, String action); + + + public void addTransition(Long from, Long to, String action, Tuple activation); + public void addSolution(Long state); + + public boolean saveDesignSpace(String path); + + public boolean renderDesignSpace(String path); + + public boolean renderDesignSpace(String path, FileFormat format); } diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java index 7456d913..9a284e24 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java @@ -1,14 +1,9 @@ package tools.refinery.visualization.internal; -import guru.nidi.graphviz.attribute.GraphAttr; -import guru.nidi.graphviz.attribute.Label; -import guru.nidi.graphviz.engine.Format; -import guru.nidi.graphviz.engine.Graphviz; -import guru.nidi.graphviz.model.MutableGraph; import tools.refinery.store.model.Interpretation; import tools.refinery.store.model.Model; import tools.refinery.store.representation.AnySymbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.store.tuple.Tuple; import tools.refinery.visualization.ModelVisualizerAdapter; import tools.refinery.visualization.ModelVisualizerStoreAdapter; @@ -16,12 +11,13 @@ import java.io.*; import java.util.HashMap; import java.util.Map; -import static guru.nidi.graphviz.model.Factory.*; - public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { private final Model model; private final ModelVisualizerStoreAdapter storeAdapter; private final Map> interpretations; + private final StringBuilder designSpaceBuilder = new StringBuilder(); + private int transitionCounter = 0; + public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) { this.model = model; this.storeAdapter = storeAdapter; @@ -46,6 +42,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { } interpretations.put(symbol, castInterpretation); } + designSpaceBuilder.append("digraph designSpace {\n"); } @Override @@ -58,36 +55,6 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return storeAdapter; } - @Override - public MutableGraph createVisualizationForCurrentModelState() { - var graph = mutGraph("model").setDirected(true).graphAttrs().add(GraphAttr.dpi(100)); - for (var entry : interpretations.entrySet()) { - var key = entry.getKey(); - var arity = key.arity(); - var cursor = entry.getValue().getAll(); - while (cursor.move()) { - if (arity == 1) { - var id = cursor.getKey().get(0); - graph.add(mutNode(String.valueOf(id)).add("label", key.name() + ": " + id)); - } else { - var from = cursor.getKey().get(0); - var to = cursor.getKey().get(1); - graph.add(mutNode(String.valueOf(from)).addLink(to(mutNode(String.valueOf(to))).with(Label.of(key.name())))); - } - } - } - return graph; - } - - @Override - public MutableGraph createVisualizationForModelState(Long version) { - var currentVersion = model.getState(); - model.restore(version); - var graph = createVisualizationForCurrentModelState(); - model.restore(currentVersion); - return graph; - } - @Override public String createDotForCurrentModelState() { var sb = new StringBuilder(); @@ -122,22 +89,6 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return graph; } - @Override - public boolean saveVisualization(MutableGraph graph, String path) { - return saveVisualization(graph, Format.PNG, path); - } - - @Override - public boolean saveVisualization(MutableGraph graph, Format format, String path) { - try { - Graphviz.fromGraph(graph).render(format).toFile(new File(path)); - return true; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - @Override public boolean saveDot(String dot, String filePath) { File file = new File(filePath); @@ -172,4 +123,65 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { } return true; } + + @Override + public void addTransition(Long from, Long to, String action) { + designSpaceBuilder.append(from).append(" -> ").append(to).append(" [label=\"").append(transitionCounter++) + .append(": ").append(action).append("\"]\n"); + + } + + @Override + public void addTransition(Long from, Long to, String action, Tuple activation) { + designSpaceBuilder.append(from).append(" -> ").append(to).append(" [label=\"").append(transitionCounter++) + .append(": ").append(action).append(" / "); + + + for (int i = 0; i < activation.getSize(); i++) { + designSpaceBuilder.append(activation.get(i)); + if (i < activation.getSize() - 1) { + designSpaceBuilder.append(", "); + } + } + designSpaceBuilder.append("\"]\n"); + } + + @Override + public void addSolution(Long state) { + designSpaceBuilder.append(state).append(" [shape = doublecircle]\n"); + } + + private String buildDesignSpaceDot() { + for (var state : storeAdapter.getStore().getStates()) { + designSpaceBuilder.append(state).append(" [URL=\"./").append(state).append(".svg\"]\n"); + } + designSpaceBuilder.append("}"); + return designSpaceBuilder.toString(); + } + + @Override + public boolean saveDesignSpace(String path) { + saveDot(buildDesignSpaceDot(), path + "/designSpace.dot"); + for (var state : storeAdapter.getStore().getStates()) { + saveDot(createDotForModelState(state), path + "/" + state + ".dot"); + } + return true; + } + + @Override + public boolean renderDesignSpace(String path) { + return renderDesignSpace(path, FileFormat.SVG); + } + + @Override + public boolean renderDesignSpace(String path, FileFormat format) { + for (var state : storeAdapter.getStore().getStates()) { + var stateDot = createDotForModelState(state); + saveDot(stateDot, path + "/" + state + ".dot"); + renderDot(stateDot, path + "/" + state + "." + format.getFormat()); + } + var designSpaceDot = buildDesignSpaceDot(); + saveDot(designSpaceDot, path + "/designSpace.dot"); + return renderDot(designSpaceDot, format, path + "/designSpace." + format.getFormat()); + } } -- cgit v1.2.3-70-g09d2