aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar nagilooh <ficsorattila96@gmail.com>2023-07-25 17:17:17 +0200
committerLibravatar nagilooh <ficsorattila96@gmail.com>2023-07-26 12:06:04 +0200
commitdd2d8a1517f3f198fe005ebf91a4f8e912609c1b (patch)
treec93cf59896c6959b588325315cd045714948dae5
parentAdd best first strategy (diff)
downloadrefinery-dd2d8a1517f3f198fe005ebf91a4f8e912609c1b.tar.gz
refinery-dd2d8a1517f3f198fe005ebf91a4f8e912609c1b.tar.zst
refinery-dd2d8a1517f3f198fe005ebf91a4f8e912609c1b.zip
Add visualization adapter
Uses Graphviz to create a visualization of the models and can save them to disk as an image or various textual representations
-rw-r--r--settings.gradle.kts1
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/Model.java4
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java4
-rw-r--r--subprojects/visualization/build.gradle.kts14
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java22
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java6
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java7
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java24
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java88
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java14
10 files changed, 184 insertions, 0 deletions
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 2b1c179d..8b53e7f7 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -17,6 +17,7 @@ include(
17 "store-query", 17 "store-query",
18 "store-query-viatra", 18 "store-query-viatra",
19 "store-reasoning", 19 "store-reasoning",
20 "visualization",
20) 21)
21 22
22for (project in rootProject.children) { 23for (project in rootProject.children) {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java
index d58d91c3..703a0720 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java
@@ -7,9 +7,11 @@ package tools.refinery.store.model;
7 7
8import tools.refinery.store.adapter.ModelAdapter; 8import tools.refinery.store.adapter.ModelAdapter;
9import tools.refinery.store.map.Versioned; 9import tools.refinery.store.map.Versioned;
10import tools.refinery.store.model.internal.VersionedInterpretation;
10import tools.refinery.store.representation.AnySymbol; 11import tools.refinery.store.representation.AnySymbol;
11import tools.refinery.store.representation.Symbol; 12import tools.refinery.store.representation.Symbol;
12 13
14import java.util.Map;
13import java.util.Optional; 15import java.util.Optional;
14 16
15public interface Model extends Versioned { 17public interface Model extends Versioned {
@@ -27,6 +29,8 @@ public interface Model extends Versioned {
27 29
28 <T> Interpretation<T> getInterpretation(Symbol<T> symbol); 30 <T> Interpretation<T> getInterpretation(Symbol<T> symbol);
29 31
32 public Map<? extends AnySymbol, ? extends Interpretation<?>> getInterpretations();
33
30 ModelDiffCursor getDiffCursor(long to); 34 ModelDiffCursor getDiffCursor(long to);
31 35
32 <T extends ModelAdapter> Optional<T> tryGetAdapter(Class<? extends T> adapterType); 36 <T extends ModelAdapter> Optional<T> tryGetAdapter(Class<? extends T> adapterType);
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java
index c5475a1a..bf6987d6 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java
@@ -187,4 +187,8 @@ public class ModelImpl implements Model {
187 public void removeListener(ModelListener listener) { 187 public void removeListener(ModelListener listener) {
188 listeners.remove(listener); 188 listeners.remove(listener);
189 } 189 }
190
191 public Map<? extends AnySymbol, ? extends Interpretation<?>> getInterpretations() {
192 return interpretations;
193 }
190} 194}
diff --git a/subprojects/visualization/build.gradle.kts b/subprojects/visualization/build.gradle.kts
new file mode 100644
index 00000000..97b1688a
--- /dev/null
+++ b/subprojects/visualization/build.gradle.kts
@@ -0,0 +1,14 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6
7plugins {
8 id("tools.refinery.gradle.java-library")
9}
10
11dependencies {
12 implementation ("guru.nidi:graphviz-java:0.18.1")
13 api(project(":refinery-store-query"))
14}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java
new file mode 100644
index 00000000..ae23e3bc
--- /dev/null
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java
@@ -0,0 +1,22 @@
1package tools.refinery.visualization;
2
3import guru.nidi.graphviz.engine.Format;
4import guru.nidi.graphviz.model.MutableGraph;
5import tools.refinery.store.adapter.ModelAdapter;
6import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl;
7
8public interface ModelVisualizerAdapter extends ModelAdapter {
9
10 ModelVisualizerStoreAdapter getStoreAdapter();
11 static ModelVisualizerBuilder builder() {
12 return new ModelVisualizerBuilderImpl();
13 }
14
15 public MutableGraph createVisualizationForCurrentModelState();
16
17 public MutableGraph createVisualizationForModelState(Long version);
18
19 public boolean saveVisualization(MutableGraph graph, String path);
20
21 public boolean saveVisualization(MutableGraph graph, Format format, String path);
22}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java
new file mode 100644
index 00000000..9c1bd0e0
--- /dev/null
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java
@@ -0,0 +1,6 @@
1package tools.refinery.visualization;
2
3import tools.refinery.store.adapter.ModelAdapterBuilder;
4
5public interface ModelVisualizerBuilder extends ModelAdapterBuilder {
6}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java
new file mode 100644
index 00000000..764de6d4
--- /dev/null
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java
@@ -0,0 +1,7 @@
1package tools.refinery.visualization;
2
3import tools.refinery.store.adapter.ModelStoreAdapter;
4import tools.refinery.store.query.ModelQueryStoreAdapter;
5
6public interface ModelVisualizerStoreAdapter extends ModelStoreAdapter {
7}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java
new file mode 100644
index 00000000..6e158c28
--- /dev/null
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java
@@ -0,0 +1,24 @@
1package tools.refinery.visualization.internal;
2
3import tools.refinery.store.adapter.ModelAdapter;
4import tools.refinery.store.model.Model;
5import tools.refinery.store.model.ModelStore;
6import tools.refinery.visualization.ModelVisualizerStoreAdapter;
7
8public class ModelVisualizeStoreAdapterImpl implements ModelVisualizerStoreAdapter {
9 private final ModelStore store;
10
11 public ModelVisualizeStoreAdapterImpl(ModelStore store) {
12 this.store = store;
13 }
14
15 @Override
16 public ModelStore getStore() {
17 return store;
18 }
19
20 @Override
21 public ModelAdapter createModelAdapter(Model model) {
22 return new ModelVisualizerAdapterImpl(model, this);
23 }
24}
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
new file mode 100644
index 00000000..475ae416
--- /dev/null
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java
@@ -0,0 +1,88 @@
1package tools.refinery.visualization.internal;
2
3import guru.nidi.graphviz.attribute.Label;
4import guru.nidi.graphviz.engine.Format;
5import guru.nidi.graphviz.engine.Graphviz;
6import guru.nidi.graphviz.model.MutableGraph;
7import tools.refinery.store.model.Model;
8import tools.refinery.visualization.ModelVisualizerAdapter;
9import tools.refinery.visualization.ModelVisualizerStoreAdapter;
10
11import java.io.File;
12import java.io.IOException;
13
14import static guru.nidi.graphviz.model.Factory.*;
15
16public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
17 private final Model model;
18 private final ModelVisualizerStoreAdapter storeAdapter;
19 public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) {
20 this.model = model;
21 this.storeAdapter = storeAdapter;
22 }
23
24 @Override
25 public Model getModel() {
26 return model;
27 }
28
29 @Override
30 public ModelVisualizerStoreAdapter getStoreAdapter() {
31 return storeAdapter;
32 }
33
34 @Override
35 public MutableGraph createVisualizationForCurrentModelState() {
36 var interpretations = model.getInterpretations();
37 MutableGraph graph = mutGraph("model").setDirected(true);
38 for (var entry : interpretations.entrySet()) {
39 var key = entry.getKey();
40 var arity = key.arity();
41 if (arity < 1 || arity > 2) {
42 continue;
43 }
44 var valueType = key.valueType();
45 // TODO: support TruthValue
46 if (valueType != Boolean.class) {
47 continue;
48 }
49 var cursor = entry.getValue().getAll();
50 while (cursor.move()) {
51 if (arity == 1) {
52 var id = cursor.getKey().get(0);
53 graph.add(mutNode(String.valueOf(id)).add("label", key.name() + ": " + id));
54 } else {
55 var from = cursor.getKey().get(0);
56 var to = cursor.getKey().get(1);
57 graph.add(mutNode(String.valueOf(from)).addLink(to(mutNode(String.valueOf(to))).with(Label.of(key.name()))));
58 }
59 }
60 }
61 return graph;
62 }
63
64 @Override
65 public MutableGraph createVisualizationForModelState(Long version) {
66 var currentVersion = model.getState();
67 model.restore(version);
68 MutableGraph graph = createVisualizationForCurrentModelState();
69 model.restore(currentVersion);
70 return graph;
71 }
72
73 @Override
74 public boolean saveVisualization(MutableGraph graph, String path) {
75 return saveVisualization(graph, Format.PNG, path);
76 }
77
78 @Override
79 public boolean saveVisualization(MutableGraph graph, Format format, String path) {
80 try {
81 Graphviz.fromGraph(graph).render(format).toFile(new File(path));
82 return true;
83 } catch (IOException e) {
84 e.printStackTrace();
85 return false;
86 }
87 }
88}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java
new file mode 100644
index 00000000..4148c24a
--- /dev/null
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java
@@ -0,0 +1,14 @@
1package tools.refinery.visualization.internal;
2
3import tools.refinery.store.adapter.AbstractModelAdapterBuilder;
4import tools.refinery.store.model.ModelStore;
5import tools.refinery.visualization.ModelVisualizerBuilder;
6
7public class ModelVisualizerBuilderImpl
8 extends AbstractModelAdapterBuilder<ModelVisualizeStoreAdapterImpl>
9 implements ModelVisualizerBuilder {
10 @Override
11 protected ModelVisualizeStoreAdapterImpl doBuild(ModelStore store) {
12 return new ModelVisualizeStoreAdapterImpl(store);
13 }
14}