diff --git a/docs/getting_started/04_mdp.ipynb b/docs/getting_started/04_mdp.ipynb index e8031fc..76a823e 100644 --- a/docs/getting_started/04_mdp.ipynb +++ b/docs/getting_started/04_mdp.ipynb @@ -25,7 +25,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 2, @@ -274,7 +274,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 11, "metadata": { "scrolled": true }, @@ -282,7 +282,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "070c8e8b2379499297b368b91977b11c", + "model_id": "3f654d1cb30b46d7aa36c6dfdce6e6cb", "version_major": 2, "version_minor": 0 }, @@ -293,10 +293,44 @@ "metadata": {}, "output_type": "display_data" }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "return_id_result('http://127.0.0.1:8889', 'TztzdYqYbmeZykfstESe', 'test message')" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "cfbba5b19efd4f048a854dee070b0458", + "model_id": "3f441d3fc7764792a27da29124d9fd0a", "version_major": 2, "version_minor": 0 }, @@ -310,7 +344,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "647715b54eef48f180a724a55259aefc", + "model_id": "6c21f529dfe546cf9d1b6c7c74a222b3", "version_major": 2, "version_minor": 0 }, @@ -346,6 +380,13 @@ "# vis2 = show.show(induced_dtmc, layout=stormvogel.layout.EXPLORE(), show_editor=False, save_and_embed=True)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/getting_started/05_simulator.ipynb b/docs/getting_started/05_simulator.ipynb index 25eb065..d97e509 100644 --- a/docs/getting_started/05_simulator.ipynb +++ b/docs/getting_started/05_simulator.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 6, "id": "a8ddc37c-66d2-43e4-8162-6be19a1d70a1", "metadata": {}, "outputs": [], @@ -23,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 7, "id": "cab40f99-3460-4497-8b9f-3d669eee1e11", "metadata": {}, "outputs": [], @@ -104,984 +104,64 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 8, "id": "c129cf62-40ca-4246-8718-5c859744e7f8", "metadata": { "scrolled": true }, "outputs": [ { - "data": { - "text/html": [ - "\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "vis = show(mdp, layout=Layout(\"layouts/monty.json\"), save_and_embed=True)" - ] - }, - { - "cell_type": "markdown", - "id": "b5b2990c-65ed-4d7b-a4b8-f303843622e5", - "metadata": {}, - "source": [ - "We want to simulate this model. That is, we start at the initial state and then we walk through the model by choosing random actions.\n", - "\n", - "When we do this, we get a partial model as a result that contains everything we discovered during this walk. \n", - "\n", - "Try running this multiple times, and observe that sometimes we get to the target and sometimes we do not." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "eb0fadc0-7bb6-4c1d-ae3e-9e16527726ab", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" + "ename": "TypeError", + "evalue": "argument of type 'bool' is not iterable", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[8], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m vis \u001b[38;5;241m=\u001b[39m show(mdp, layout\u001b[38;5;241m=\u001b[39m\u001b[43mLayout\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mlayouts/monty.json\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m, save_and_embed\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/layout.py:29\u001b[0m, in \u001b[0;36mLayout.__init__\u001b[0;34m(self, path, path_relative)\u001b[0m\n\u001b[1;32m 27\u001b[0m default_str \u001b[38;5;241m=\u001b[39m f\u001b[38;5;241m.\u001b[39mread()\n\u001b[1;32m 28\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_dict: \u001b[38;5;28mdict\u001b[39m \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mloads(default_str)\n\u001b[0;32m---> 29\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpath\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpath_relative\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/layout.py:43\u001b[0m, in \u001b[0;36mLayout.load\u001b[0;34m(self, path, path_relative)\u001b[0m\n\u001b[1;32m 41\u001b[0m parsed_dict \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mloads(parsed_str)\n\u001b[1;32m 42\u001b[0m \u001b[38;5;66;03m# Combine the parsed dict with default to fill missing keys as default values.\u001b[39;00m\n\u001b[0;32m---> 43\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlayout: \u001b[38;5;28mdict\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[43mstormvogel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrdict\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmerge_dict\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 44\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdefault_dict\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparsed_dict\u001b[49m\n\u001b[1;32m 45\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 47\u001b[0m \u001b[38;5;66;03m# Load in schema for the dict_editor.\u001b[39;00m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mjoin(PACKAGE_ROOT_DIR, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlayouts/schema.json\u001b[39m\u001b[38;5;124m\"\u001b[39m)) \u001b[38;5;28;01mas\u001b[39;00m f:\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/rdict.py:46\u001b[0m, in \u001b[0;36mmerge_dict\u001b[0;34m(dict1, dict2)\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(val, \u001b[38;5;28mdict\u001b[39m):\n\u001b[1;32m 45\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m key \u001b[38;5;129;01min\u001b[39;00m dict2 \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mtype\u001b[39m(dict2[key] \u001b[38;5;241m==\u001b[39m \u001b[38;5;28mdict\u001b[39m):\n\u001b[0;32m---> 46\u001b[0m \u001b[43mmerge_dict\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdict1\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdict2\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 47\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m key \u001b[38;5;129;01min\u001b[39;00m dict2:\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/rdict.py:48\u001b[0m, in \u001b[0;36mmerge_dict\u001b[0;34m(dict1, dict2)\u001b[0m\n\u001b[1;32m 46\u001b[0m merge_dict(dict1[key], dict2[key])\n\u001b[1;32m 47\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 48\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mkey\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mdict2\u001b[49m:\n\u001b[1;32m 49\u001b[0m dict1[key] \u001b[38;5;241m=\u001b[39m dict2[key]\n\u001b[1;32m 51\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m key, val \u001b[38;5;129;01min\u001b[39;00m dict2\u001b[38;5;241m.\u001b[39mitems():\n", + "\u001b[0;31mTypeError\u001b[0m: argument of type 'bool' is not iterable" + ] + } + ], + "source": [ + "vis = show(mdp, layout=Layout(\"layouts/monty.json\"), save_and_embed=True)" + ] + }, + { + "cell_type": "markdown", + "id": "b5b2990c-65ed-4d7b-a4b8-f303843622e5", + "metadata": {}, + "source": [ + "We want to simulate this model. That is, we start at the initial state and then we walk through the model by choosing random actions.\n", + "\n", + "When we do this, we get a partial model as a result that contains everything we discovered during this walk. \n", + "\n", + "Try running this multiple times, and observe that sometimes we get to the target and sometimes we do not." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "eb0fadc0-7bb6-4c1d-ae3e-9e16527726ab", + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "argument of type 'bool' is not iterable", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[4], line 12\u001b[0m\n\u001b[1;32m 8\u001b[0m partial_model \u001b[38;5;241m=\u001b[39m stormvogel\u001b[38;5;241m.\u001b[39msimulator\u001b[38;5;241m.\u001b[39msimulate(mdp, steps\u001b[38;5;241m=\u001b[39msteps, seed\u001b[38;5;241m=\u001b[39mseed)\n\u001b[1;32m 9\u001b[0m \u001b[38;5;66;03m# We could also provide a seed.\u001b[39;00m\n\u001b[1;32m 10\u001b[0m \u001b[38;5;66;03m#partial_model = stormvogel.simulator.simulate(mdp, steps=steps, seed=seed)\u001b[39;00m\n\u001b[0;32m---> 12\u001b[0m vis \u001b[38;5;241m=\u001b[39m show(partial_model, save_and_embed\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, layout\u001b[38;5;241m=\u001b[39m\u001b[43mLayout\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mlayouts/small_monty.json\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m)\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/layout.py:29\u001b[0m, in \u001b[0;36mLayout.__init__\u001b[0;34m(self, path, path_relative)\u001b[0m\n\u001b[1;32m 27\u001b[0m default_str \u001b[38;5;241m=\u001b[39m f\u001b[38;5;241m.\u001b[39mread()\n\u001b[1;32m 28\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_dict: \u001b[38;5;28mdict\u001b[39m \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mloads(default_str)\n\u001b[0;32m---> 29\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpath\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpath_relative\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/layout.py:43\u001b[0m, in \u001b[0;36mLayout.load\u001b[0;34m(self, path, path_relative)\u001b[0m\n\u001b[1;32m 41\u001b[0m parsed_dict \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mloads(parsed_str)\n\u001b[1;32m 42\u001b[0m \u001b[38;5;66;03m# Combine the parsed dict with default to fill missing keys as default values.\u001b[39;00m\n\u001b[0;32m---> 43\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlayout: \u001b[38;5;28mdict\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[43mstormvogel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrdict\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmerge_dict\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 44\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdefault_dict\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparsed_dict\u001b[49m\n\u001b[1;32m 45\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 47\u001b[0m \u001b[38;5;66;03m# Load in schema for the dict_editor.\u001b[39;00m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mjoin(PACKAGE_ROOT_DIR, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlayouts/schema.json\u001b[39m\u001b[38;5;124m\"\u001b[39m)) \u001b[38;5;28;01mas\u001b[39;00m f:\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/rdict.py:46\u001b[0m, in \u001b[0;36mmerge_dict\u001b[0;34m(dict1, dict2)\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(val, \u001b[38;5;28mdict\u001b[39m):\n\u001b[1;32m 45\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m key \u001b[38;5;129;01min\u001b[39;00m dict2 \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mtype\u001b[39m(dict2[key] \u001b[38;5;241m==\u001b[39m \u001b[38;5;28mdict\u001b[39m):\n\u001b[0;32m---> 46\u001b[0m \u001b[43mmerge_dict\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdict1\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdict2\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 47\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m key \u001b[38;5;129;01min\u001b[39;00m dict2:\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/rdict.py:48\u001b[0m, in \u001b[0;36mmerge_dict\u001b[0;34m(dict1, dict2)\u001b[0m\n\u001b[1;32m 46\u001b[0m merge_dict(dict1[key], dict2[key])\n\u001b[1;32m 47\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 48\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mkey\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mdict2\u001b[49m:\n\u001b[1;32m 49\u001b[0m dict1[key] \u001b[38;5;241m=\u001b[39m dict2[key]\n\u001b[1;32m 51\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m key, val \u001b[38;5;129;01min\u001b[39;00m dict2\u001b[38;5;241m.\u001b[39mitems():\n", + "\u001b[0;31mTypeError\u001b[0m: argument of type 'bool' is not iterable" + ] } ], "source": [ @@ -1116,236 +196,19 @@ "metadata": {}, "outputs": [ { - "data": { - "text/html": [ - "\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" + "ename": "TypeError", + "evalue": "argument of type 'bool' is not iterable", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[5], line 8\u001b[0m\n\u001b[1;32m 5\u001b[0m scheduler \u001b[38;5;241m=\u001b[39m stormvogel\u001b[38;5;241m.\u001b[39mresult\u001b[38;5;241m.\u001b[39mScheduler(mdp, taken_actions)\n\u001b[1;32m 7\u001b[0m partial_model \u001b[38;5;241m=\u001b[39m stormvogel\u001b[38;5;241m.\u001b[39msimulator\u001b[38;5;241m.\u001b[39msimulate(mdp, steps\u001b[38;5;241m=\u001b[39msteps, scheduler\u001b[38;5;241m=\u001b[39mscheduler, seed\u001b[38;5;241m=\u001b[39mseed)\n\u001b[0;32m----> 8\u001b[0m vis \u001b[38;5;241m=\u001b[39m show(partial_model, save_and_embed\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, layout\u001b[38;5;241m=\u001b[39m\u001b[43mLayout\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mlayouts/small_monty.json\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m)\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/layout.py:29\u001b[0m, in \u001b[0;36mLayout.__init__\u001b[0;34m(self, path, path_relative)\u001b[0m\n\u001b[1;32m 27\u001b[0m default_str \u001b[38;5;241m=\u001b[39m f\u001b[38;5;241m.\u001b[39mread()\n\u001b[1;32m 28\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdefault_dict: \u001b[38;5;28mdict\u001b[39m \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mloads(default_str)\n\u001b[0;32m---> 29\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpath\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpath_relative\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/layout.py:43\u001b[0m, in \u001b[0;36mLayout.load\u001b[0;34m(self, path, path_relative)\u001b[0m\n\u001b[1;32m 41\u001b[0m parsed_dict \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mloads(parsed_str)\n\u001b[1;32m 42\u001b[0m \u001b[38;5;66;03m# Combine the parsed dict with default to fill missing keys as default values.\u001b[39;00m\n\u001b[0;32m---> 43\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlayout: \u001b[38;5;28mdict\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[43mstormvogel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrdict\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmerge_dict\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 44\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdefault_dict\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparsed_dict\u001b[49m\n\u001b[1;32m 45\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 47\u001b[0m \u001b[38;5;66;03m# Load in schema for the dict_editor.\u001b[39;00m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mjoin(PACKAGE_ROOT_DIR, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlayouts/schema.json\u001b[39m\u001b[38;5;124m\"\u001b[39m)) \u001b[38;5;28;01mas\u001b[39;00m f:\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/rdict.py:46\u001b[0m, in \u001b[0;36mmerge_dict\u001b[0;34m(dict1, dict2)\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(val, \u001b[38;5;28mdict\u001b[39m):\n\u001b[1;32m 45\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m key \u001b[38;5;129;01min\u001b[39;00m dict2 \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mtype\u001b[39m(dict2[key] \u001b[38;5;241m==\u001b[39m \u001b[38;5;28mdict\u001b[39m):\n\u001b[0;32m---> 46\u001b[0m \u001b[43mmerge_dict\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdict1\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdict2\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 47\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m key \u001b[38;5;129;01min\u001b[39;00m dict2:\n", + "File \u001b[0;32m~/git/stormvogel/env/lib/python3.12/site-packages/stormvogel/rdict.py:48\u001b[0m, in \u001b[0;36mmerge_dict\u001b[0;34m(dict1, dict2)\u001b[0m\n\u001b[1;32m 46\u001b[0m merge_dict(dict1[key], dict2[key])\n\u001b[1;32m 47\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 48\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mkey\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mdict2\u001b[49m:\n\u001b[1;32m 49\u001b[0m dict1[key] \u001b[38;5;241m=\u001b[39m dict2[key]\n\u001b[1;32m 51\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m key, val \u001b[38;5;129;01min\u001b[39;00m dict2\u001b[38;5;241m.\u001b[39mitems():\n", + "\u001b[0;31mTypeError\u001b[0m: argument of type 'bool' is not iterable" + ] } ], "source": [ diff --git a/stormvogel/html_templates.py b/stormvogel/html_templates.py index 8b35e83..25485ec 100644 --- a/stormvogel/html_templates.py +++ b/stormvogel/html_templates.py @@ -46,26 +46,30 @@ function makeNeighborsVisible(homeId) { //var ids = network.getConnectedNodes(myNode); homeNode = nodes.get(homeId); - var edgeIds = network.getConnectedEdges(homeId, 'to'); + + // Make outgoing nodes visible + var nodeIds = network.getConnectedNodes(homeId, "to"); + for (let i = 0; i < nodeIds.length; i++) { + var toNodeId = nodeIds[i]; + var toNode = nodes.get(toNodeId); + toNode["hidden"] = false; + toNode["physics"] = true; + toNode["x"] = network.getPosition(homeId)["x"]; + toNode["y"] = network.getPosition(homeId)["y"]; + nodes.update(toNode); + } + // Make edges visible, if both of the nodes are also visible + var edgeIds = network.getConnectedEdges(homeId); for (let i = 0; i < edgeIds.length; i++) { var edgeId = edgeIds[i]; var edge = edges.get(edgeId); - var nodeId = edge.to; - var node = nodes.get(nodeId); - - if (node["hidden"]) { - node["hidden"] = false; - node["physics"] = true; - // node["x"] = network.getPosition(homeId)["x"]; - // node["y"] = network.getPosition(homeId)["y"]; - nodes.update(node); - // node["x"] = undefined; - // node["y"] = undefined; - // nodes.update(node); + var fromNode = nodes.get(edge.from); + var toNode = nodes.get(edge.to); + if ((! fromNode["hidden"]) && (! toNode["hidden"])) { + edge["hidden"] = false; + edge["physics"] = true; + edges.update(edge); } - edge["hidden"] = false; - edge["physics"] = true; - edges.update(edge); } }; function makeNodeVisible(nodeId) {