Skip to content

Commit

Permalink
Progress on saving layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
YouGuessedMyName committed Jul 1, 2024
1 parent 9df743e commit 6950e78
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 26 deletions.
3 changes: 3 additions & 0 deletions notebooks/custom_layout.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"color": "red"
}
71 changes: 71 additions & 0 deletions notebooks/layouts.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "e0d2c1f7-3a10-4f30-a4d1-2d446de06487",
"metadata": {},
"outputs": [],
"source": [
"import stormvogel.layout\n",
"from stormvogel.layout import DEFAULT"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "8c98f637-ed9c-430b-b414-09c665b307f8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'color': 'red'}\n",
"{'color': 'red'}\n",
"{'color': 'blue'}\n",
"{'color': 'blue'}\n"
]
}
],
"source": [
"# Import custom layout\n",
"l1 = stormvogel.layout.Layout(custom=True, custom_path=\"custom_layout.json\")\n",
"l2 = stormvogel.layout.Layout(custom=True, custom_path=\"/home/ivo/git/stormvogel/notebooks/custom_layout.json\", custom_path_relative=False)\n",
"# Import template layout\n",
"l3 = stormvogel.layout.Layout(custom=False, template_path=\"layouts/default.json\")\n",
"l4 = stormvogel.layout.Layout(custom=False, template_path=DEFAULT)\n",
"l5 = "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9198a4b4-12cd-47a4-8950-278c18023192",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
2 changes: 1 addition & 1 deletion notebooks/model.html
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ <h1></h1>
// adding nodes and edges to the graph
data = {nodes: nodes, edges: edges};

var options = {"nodes": {"color": {"background": "white", "border": "black"}}, "physics": {"barnesHut": {"gravitationalConstant": -22660, "centralGravity": 4.5, "springLength": 50, "springConstant": 0.08, "damping": 0.32, "avoidOverlap": 1}, "minVelocity": 0.75}};
var options = {"nodes": {"color": {"background": "blue", "border": "black"}}};



Expand Down
13 changes: 11 additions & 2 deletions notebooks/study.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@
"cells": [
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 1,
"id": "0df1511e-565d-45d0-93a8-adafbfaaaefa",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"var options = {\n",
" \"nodes\": {\n",
" \"color\": {\n",
" \"background\": \"blue\",\n",
" \"border\": \"black\"\n",
" }\n",
" }\n",
"}\n",
"model.html\n"
]
},
Expand All @@ -28,7 +37,7 @@
" "
],
"text/plain": [
"<IPython.lib.display.IFrame at 0x7f8c99fba190>"
"<IPython.lib.display.IFrame at 0x7f9fbf8dcc10>"
]
},
"metadata": {},
Expand Down
71 changes: 71 additions & 0 deletions stormvogel/layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Contains the code responsible for saving/loading layouts and modifying them interactively."""

from pyvis.network import Network
import os
import json

DEFAULT = "layouts/default.json"


class Layout:
layout: dict

def __init__(
self,
custom: bool,
path: str | None = None,
path_relative: bool = True,
template_path: str = DEFAULT,
) -> None:
"""Load a new Layout from a json file. Use either a custom or a template file.
Args:
custom (bool, optional): If set to true, stormvogel will look for your custom layout.json file. Otherwise a template will be used.
path (str, optional): Relavant if custom is true. Path to your custom layout file, relative to the current working directory. Defaults to None.
path_relative (bool): Relavant if custom is true. If set to true, then stormvogel will look for a custom layout file relative to the current working directory.
template_path (str, optional): Relavant if custom is false. Path to a template layout files.
These are stored in the folder layouts. For simplicity, we recommed using the constants DEFAULT, etc.
Defaults to DEFAULT (="layouts/default.json").
"""
if custom:
if path is None:
raise Exception(
"If custom is set to true, then the path needs to be set."
)
cwd = os.getcwd()
if path_relative:
complete_path = os.path.join(cwd, path)
else:
complete_path = path
with open(complete_path) as f:
json_string = f.read()
self.layout = json.loads(json_string)
else:
package_root_dir = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(package_root_dir, template_path)) as f:
json_string = f.read()
self.layout = json.loads(json_string)

def set_nt_layout(self, nt: Network) -> None:
"""Set the layout of the network passed as the arugment."""
# We here use <> instead of {} because the f-string formatting already uses them.
option_string = f"""
var options = <
"nodes": <
"color": <
"background": "{self.layout["color"]}",
"border": "black"
>
>
>""".replace("<", "{").replace(">", "}")
print(option_string)
nt.set_options(option_string)

def save(self) -> None:
raise NotImplementedError()

def show_buttons(self) -> None:
raise NotImplementedError()

def __str__(self) -> str:
raise NotImplementedError()
3 changes: 3 additions & 0 deletions stormvogel/layouts/default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"color": "blue"
}
34 changes: 11 additions & 23 deletions stormvogel/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from pyvis.network import Network
from stormvogel.model import Model, EmptyAction, Number
from stormvogel.layout import Layout
from ipywidgets import interact
from IPython.display import display
from fractions import Fraction
Expand All @@ -10,7 +11,10 @@
class Visualization:
"""Handles visualization of a Model using a pyvis Network."""

name: str
g: Network
ACTION_ID_OFFSET = 10**8
layout: Layout
# In the visualization, both actions and states are nodes with an id.
# This offset is used to keep their ids from colliding. It should be some high constant.

Expand All @@ -20,6 +24,7 @@ def __init__(
name: str = "model",
notebook: bool = True,
cdn_resources: str = "remote",
layout: Layout | None = None,
) -> None:
"""Create visualization of a Model using a pyvis Network
Expand All @@ -37,29 +42,12 @@ def __init__(
self.g = Network(notebook=notebook, directed=True, cdn_resources=cdn_resources)
self.__add_states()
self.__add_transitions()
self.__set_layout()

def __set_layout(self):
self.g.set_options("""
var options = {
"nodes": {
"color": {
"background": "white",
"border": "black"
}
},
"physics": {
"barnesHut": {
"gravitationalConstant": -22660,
"centralGravity": 4.5,
"springLength": 50,
"springConstant": 0.08,
"damping": 0.32,
"avoidOverlap": 1
},
"minVelocity": 0.75
}
}""")
if layout is None:
self.layout = Layout(custom=False)
else:
self.layout = layout

self.layout.set_nt_layout(self.g)

def __add_states(self):
"""For each state in the model, add a node to the graph."""
Expand Down

0 comments on commit 6950e78

Please sign in to comment.