diff options
Diffstat (limited to 'subprojects/visualization')
7 files changed, 175 insertions, 0 deletions
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 | |||
7 | plugins { | ||
8 | id("tools.refinery.gradle.java-library") | ||
9 | } | ||
10 | |||
11 | dependencies { | ||
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 @@ | |||
1 | package tools.refinery.visualization; | ||
2 | |||
3 | import guru.nidi.graphviz.engine.Format; | ||
4 | import guru.nidi.graphviz.model.MutableGraph; | ||
5 | import tools.refinery.store.adapter.ModelAdapter; | ||
6 | import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl; | ||
7 | |||
8 | public 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 @@ | |||
1 | package tools.refinery.visualization; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelAdapterBuilder; | ||
4 | |||
5 | public 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 @@ | |||
1 | package tools.refinery.visualization; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelStoreAdapter; | ||
4 | import tools.refinery.store.query.ModelQueryStoreAdapter; | ||
5 | |||
6 | public 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 @@ | |||
1 | package tools.refinery.visualization.internal; | ||
2 | |||
3 | import tools.refinery.store.adapter.ModelAdapter; | ||
4 | import tools.refinery.store.model.Model; | ||
5 | import tools.refinery.store.model.ModelStore; | ||
6 | import tools.refinery.visualization.ModelVisualizerStoreAdapter; | ||
7 | |||
8 | public 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 @@ | |||
1 | package tools.refinery.visualization.internal; | ||
2 | |||
3 | import guru.nidi.graphviz.attribute.Label; | ||
4 | import guru.nidi.graphviz.engine.Format; | ||
5 | import guru.nidi.graphviz.engine.Graphviz; | ||
6 | import guru.nidi.graphviz.model.MutableGraph; | ||
7 | import tools.refinery.store.model.Model; | ||
8 | import tools.refinery.visualization.ModelVisualizerAdapter; | ||
9 | import tools.refinery.visualization.ModelVisualizerStoreAdapter; | ||
10 | |||
11 | import java.io.File; | ||
12 | import java.io.IOException; | ||
13 | |||
14 | import static guru.nidi.graphviz.model.Factory.*; | ||
15 | |||
16 | public 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 @@ | |||
1 | package tools.refinery.visualization.internal; | ||
2 | |||
3 | import tools.refinery.store.adapter.AbstractModelAdapterBuilder; | ||
4 | import tools.refinery.store.model.ModelStore; | ||
5 | import tools.refinery.visualization.ModelVisualizerBuilder; | ||
6 | |||
7 | public class ModelVisualizerBuilderImpl | ||
8 | extends AbstractModelAdapterBuilder<ModelVisualizeStoreAdapterImpl> | ||
9 | implements ModelVisualizerBuilder { | ||
10 | @Override | ||
11 | protected ModelVisualizeStoreAdapterImpl doBuild(ModelStore store) { | ||
12 | return new ModelVisualizeStoreAdapterImpl(store); | ||
13 | } | ||
14 | } | ||