diff --git a/docs/index.rst b/docs/index.rst index eba99b0c..7be6bb99 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -20,26 +20,6 @@ An interactive visual tool for modeling and simulating nuclear fuel cycle compon :alt: Node.js 18+ -=============================== -Statement of Need -=============================== - -System modeling is a critical aspect of nuclear engineering that requires sophisticated tools to analyze material flows, reactor performance, and waste management strategies. PathView addresses the need for: - -**Accessibility** - Traditional system simulation tools are often complex, proprietary, or require extensive training. This tool provides an intuitive visual interface that makes system modeling accessible to students, researchers, and professionals. - -**Interactivity** - Static models and command-line tools limit exploration and understanding. Our interactive visual approach allows users to build, modify, and experiment with system scenarios in real-time. - -**Educational Value** - The visual nature of the tool makes it ideal for teaching system concepts, allowing students to see the connections between different components and understand material flows. - -**Research Flexibility** - Researchers need tools that can be easily modified and extended. The open-source nature and modular architecture enable customization for specific research needs. - -**Modern Technology Stack** - Built with modern web technologies (React, Python) that ensure maintainability, extensibility, and cross-platform compatibility. =============================== Installation Guide @@ -56,10 +36,6 @@ Before installing PathView, ensure your system meets the following requirements: - pip for Python package management - Git (for development) -**Supported Operating Systems:** - - Linux (Ubuntu 20.04+, CentOS 8+) - - macOS 10.15+ - - Windows 10+ Installation Steps ------------------ @@ -92,7 +68,15 @@ Installation Steps # On Windows: venv\Scripts\activate + + Alternatively, you can use Conda: + .. code-block:: bash + conda create -n pathview python=3.8 + conda activate pathview + pip install --upgrade pip + pip install -e . + 4. **Install Backend Dependencies** .. code-block:: bash @@ -110,57 +94,73 @@ Installation Steps - Frontend: http://localhost:5173 - Backend API: http://localhost:8000 -Troubleshooting ---------------- - -**Common Issues:** - -- **Node.js version conflicts**: Use nvm to manage Node.js versions -- **Python path issues**: Ensure Python 3.8+ is in your PATH -- **Port conflicts**: Check if ports 5173 or 8000 are already in use -- **Permission errors**: Use appropriate permissions for installation directories - =============================== Example Usage =============================== -Quick Start Example -------------------- - Here's a simple example to get you started with PathView: -WIP - - -Use Cases ---------- +1. **Start the Application** + + After installation, launch PathView: + + .. code-block:: bash + + npm run start:both + + Navigate to http://localhost:5173 in your browser. -**Educational Scenarios** - - Simple fuel cycle for classroom demonstrations - - Impact of tritium breeding ratio for fusion reactors +2. **Load Example Files** + + PathView includes several pre-built example graphs in the `example_graphs/ `_ directory that demonstrate different functionality: + + - ``harmonic_oscillator.json`` - Simple oscillator simulation + - ``pid.json`` - PID controller example + - ``festim_two_walls.json`` - Two-wall diffusion model + - ``linear_feedback.json`` - Linear feedback system + - ``spectrum.json`` - Spectral analysis example + + To load an example: + + - Use the file import functionality in the application + - Select any ``.json`` file from the ``example_graphs/`` directory + - The graph will load with pre-configured nodes and connections + - Click the Run button to run the example -**Research Applications** - - Advanced reactor fuel cycle analysis - - Multi-recycling scenarios - - Waste minimization strategies +3. **Create Your Own Graphs** + + - Drag and drop nodes from the sidebar + - Connect nodes by dragging from output handles to input handles + - Configure node parameters in the properties panel + - Use the simulation controls to run your model -**Planning and Analysis** - - Regional fuel cycle infrastructure planning - - Economic optimization studies - - Material flow tracking =============================== Roadmap =============================== -WIP +**Core Functionality & Solvers** + - Support more PathSim solvers + - User-defined block class (ie. users writing their own Python classes for blocks) + - Support for user plugins (eg. Chem.Eng., fuel cycle blocks, thermodynamic models, etc.) + +**Graph Management & Import/Export** + - Export graph as Subsystem and load it back + +**User Interface & Experience** + - Improved UI/UX + - Capability to rotate/flip nodes + - Enhanced visualization options + - More styling options for nodes and edges + +**Documentation & Examples** + - More example scenarios + - Annotations and comments on graph =============================== Community Guidelines =============================== -Welcome to the PathView community! We're committed to fostering an inclusive, collaborative environment for all contributors. - Code of Conduct ---------------- @@ -171,7 +171,7 @@ Contributing Guidelines **Getting Started** 1. Fork the repository - 2. Create a feature branch (``git checkout -b feature/awesome-feature``) + 2. Create a feature branch (``git checkout -b awesome-feature``) 3. Make your changes 4. Add tests for new functionality if needed 5. Ensure all tests pass diff --git a/example_graphs/baby.json b/example_graphs/baby.json deleted file mode 100644 index f9377337..00000000 --- a/example_graphs/baby.json +++ /dev/null @@ -1,826 +0,0 @@ -{ - "version": { - "pathsim_version": "0.8.2", - "pathview_version": "0.1.dev470+g017515800.d20250812" - }, - "nodes": [ - { - "data": { - "gain": "-1", - "label": "x (-1)", - "nodeColor": "#DDE6ED" - }, - "dragging": false, - "id": "4", - "measured": { - "height": 80, - "width": 90 - }, - "position": { - "x": 508, - "y": 369 - }, - "selected": false, - "type": "amplifier" - }, - { - "data": { - "label": "Neutron rate", - "labels": "", - "sampling_rate": "", - "t_wait": "", - "nodeColor": "#DDE6ED" - }, - "dragging": false, - "id": "6", - "measured": { - "height": 64, - "width": 64 - }, - "position": { - "x": 738, - "y": 385 - }, - "selected": false, - "type": "adder" - }, - { - "data": { - "gain": "3e-3", - "label": "TBR", - "nodeColor": "#DDE6ED" - }, - "dragging": false, - "id": "7", - "measured": { - "height": 80, - "width": 90 - }, - "position": { - "x": 912, - "y": 486 - }, - "selected": false, - "type": "amplifier" - }, - { - "data": { - "initial_value": "", - "label": "BABY", - "residence_time": "(k_IV + k_OV)/baby_vol", - "source_term": "", - "nodeColor": "#DDE6ED" - }, - "dragging": false, - "id": "8", - "measured": { - "height": 120, - "width": 200 - }, - "position": { - "x": 1020.1905095320806, - "y": 573.6390158215457 - }, - "selected": false, - "type": "process" - }, - { - "data": { - "label": "IV vial activity", - "labels": "", - "sampling_rate": "", - "t_wait": "", - "nodeColor": "#DDE6ED" - }, - "dragging": false, - "id": "21", - "measured": { - "height": 140, - "width": 120 - }, - "position": { - "x": 1949.5229665105167, - "y": 563.941606900507 - }, - "selected": false, - "type": "scope" - }, - { - "data": { - "f1": "0.01", - "f2": "0.99", - "label": "soluble vs insoluble", - "nodeColor": "#DDE6ED" - }, - "dragging": false, - "id": "1", - "measured": { - "height": 120, - "width": 120 - }, - "position": { - "x": 1394.0782538373574, - "y": 743.9802025169162 - }, - "selected": false, - "type": "splitter2" - }, - { - "id": "23", - "type": "bubbler", - "position": { - "x": 1595, - "y": 722 - }, - "data": { - "label": "IV bubbler", - "conversion_efficiency": "0.95", - "vial_efficiency": "0.9", - "replacement_times": "np.arange(5, 50, step=3)", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 230, - "height": 160 - }, - "selected": false, - "dragging": false - }, - { - "id": "24", - "type": "splitter2", - "position": { - "x": 1193, - "y": 851 - }, - "data": { - "label": "IV vs OV", - "f1": "k_IV/(k_IV + k_OV)", - "f2": "k_OV/(k_IV + k_OV)", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 120 - }, - "selected": false, - "dragging": false - }, - { - "id": "25", - "type": "splitter2", - "position": { - "x": 1410.747877541758, - "y": 965.2139451372932 - }, - "data": { - "label": "soluble vs insoluble", - "f1": "0.01", - "f2": "0.99", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 120 - }, - "selected": false, - "dragging": false - }, - { - "id": "26", - "type": "bubbler", - "position": { - "x": 1602.4670834180595, - "y": 970.2206053879095 - }, - "data": { - "label": "OV bubbler", - "conversion_efficiency": "0.95", - "vial_efficiency": "0.9", - "replacement_times": "np.arange(5, 50, step=5)", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 230, - "height": 160 - }, - "selected": false, - "dragging": false - }, - { - "id": "27", - "type": "integrator", - "position": { - "x": 2059.579367811878, - "y": 919.8031067000171 - }, - "data": { - "label": "environment", - "initial_value": "", - "reset_times": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 200, - "height": 48 - }, - "selected": false, - "dragging": false - }, - { - "id": "28", - "type": "scope", - "position": { - "x": 1923.4902343023584, - "y": 1097.1334152526842 - }, - "data": { - "label": "OV vial activity", - "labels": "", - "sampling_rate": "", - "t_wait": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 140 - }, - "selected": false, - "dragging": false - }, - { - "id": "30", - "type": "scope", - "position": { - "x": 916, - "y": 786 - }, - "data": { - "label": "BABY inventory", - "labels": "", - "sampling_rate": "", - "t_wait": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 140 - }, - "selected": false, - "dragging": false - }, - { - "id": "31", - "type": "stepsource", - "position": { - "x": 435.96282260684967, - "y": 213.2008701092014 - }, - "data": { - "label": "Stepsource", - "amplitude": "1", - "tau": "4", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 120 - }, - "selected": false, - "dragging": false - }, - { - "id": "32", - "type": "stepsource", - "position": { - "x": 324.7489008596274, - "y": 356.4037177393149 - }, - "data": { - "label": "Stepsource", - "amplitude": "1", - "tau": "2", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 120 - }, - "selected": false, - "dragging": false - }, - { - "id": "33", - "type": "scope", - "position": { - "x": 889.5927227230428, - "y": 175.9984179832702 - }, - "data": { - "label": "Neutron source", - "labels": "", - "sampling_rate": "", - "t_wait": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 140 - }, - "selected": true, - "dragging": false - } - ], - "edges": [ - { - "data": {}, - "id": "e4-6", - "markerEnd": { - "color": "#ECDFCC", - "height": 20, - "type": "arrowclosed", - "width": 20 - }, - "source": "4", - "sourceHandle": null, - "style": { - "stroke": "#ECDFCC", - "strokeWidth": 2 - }, - "target": "6", - "targetHandle": null, - "type": "smoothstep" - }, - { - "data": {}, - "id": "e6-7", - "markerEnd": { - "color": "#ECDFCC", - "height": 20, - "type": "arrowclosed", - "width": 20 - }, - "source": "6", - "sourceHandle": null, - "style": { - "stroke": "#ECDFCC", - "strokeWidth": 2 - }, - "target": "7", - "targetHandle": null, - "type": "smoothstep" - }, - { - "data": {}, - "id": "e7-8", - "markerEnd": { - "color": "#ECDFCC", - "height": 20, - "type": "arrowclosed", - "width": 20 - }, - "source": "7", - "sourceHandle": null, - "style": { - "stroke": "#ECDFCC", - "strokeWidth": 2 - }, - "target": "8", - "targetHandle": null, - "type": "smoothstep" - }, - { - "id": "e24-1-from_source1", - "source": "24", - "target": "1", - "sourceHandle": "source1", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e1-23-from_source1-to_sample_in_soluble", - "source": "1", - "target": "23", - "sourceHandle": "source1", - "targetHandle": "sample_in_soluble", - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e1-23-from_source2-to_sample_in_insoluble", - "source": "1", - "target": "23", - "sourceHandle": "source2", - "targetHandle": "sample_in_insoluble", - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e23-21-from_vial1", - "source": "23", - "target": "21", - "sourceHandle": "vial1", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e23-21-from_vial2", - "source": "23", - "target": "21", - "sourceHandle": "vial2", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e23-21-from_vial3", - "source": "23", - "target": "21", - "sourceHandle": "vial3", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e23-21-from_vial4", - "source": "23", - "target": "21", - "sourceHandle": "vial4", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e8-24-from_mass_flow_rate", - "source": "8", - "target": "24", - "sourceHandle": "mass_flow_rate", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e24-25-from_source2", - "source": "24", - "target": "25", - "sourceHandle": "source2", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e25-26-from_source1-to_sample_in_soluble", - "source": "25", - "target": "26", - "sourceHandle": "source1", - "targetHandle": "sample_in_soluble", - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e25-26-from_source2-to_sample_in_insoluble", - "source": "25", - "target": "26", - "sourceHandle": "source2", - "targetHandle": "sample_in_insoluble", - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e23-27-from_sample_out", - "source": "23", - "target": "27", - "sourceHandle": "sample_out", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e26-27-from_sample_out", - "source": "26", - "target": "27", - "sourceHandle": "sample_out", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e26-28-from_vial1", - "source": "26", - "target": "28", - "sourceHandle": "vial1", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e26-28-from_vial2", - "source": "26", - "target": "28", - "sourceHandle": "vial2", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e26-28-from_vial3", - "source": "26", - "target": "28", - "sourceHandle": "vial3", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e26-28-from_vial4", - "source": "26", - "target": "28", - "sourceHandle": "vial4", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e8-30-from_inv", - "source": "8", - "target": "30", - "sourceHandle": "inv", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e31-4", - "source": "31", - "target": "4", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e32-6", - "source": "32", - "target": "6", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e6-33", - "source": "6", - "target": "33", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - } - ], - "nodeCounter": 34, - "solverParams": { - "dt": "0.01", - "dt_min": "1e-6", - "dt_max": "1.0", - "Solver": "SSPRK22", - "tolerance_fpi": "1e-6", - "iterations_max": "100", - "log": "true", - "simulation_duration": "50.0", - "extra_params": "{\"tolerance_lte_rel\":1e-4, \"tolerance_lte_abs\":1e-9}" - }, - "globalVariables": [ - { - "id": "1753792090540", - "name": "baby_vol", - "value": "1", - "nameError": false - }, - { - "id": "1753797344108", - "name": "k_IV", - "value": "5", - "nameError": false - }, - { - "id": "1753797380350", - "name": "k_OV", - "value": "1", - "nameError": false - } - ], - "events": [], - "pythonCode": "# Define your Python variables and functions here\n# Example:\n# my_variable = 42\n# def my_function(x):\n# return x * 2\n" -} \ No newline at end of file diff --git a/example_graphs/events.json b/example_graphs/events.json deleted file mode 100644 index 56f111c8..00000000 --- a/example_graphs/events.json +++ /dev/null @@ -1,148 +0,0 @@ -{ - "version": { - "pathsim_version": "0.8.2", - "pathview_version": "0.1.dev470+g017515800.d20250812" - }, - "nodes": [ - { - "id": "0", - "type": "constant", - "position": { - "x": 443.74999237060547, - "y": 132.24999809265137 - }, - "data": { - "label": "source", - "value": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 206, - "height": 54 - }, - "selected": true - }, - { - "id": "1", - "type": "integrator", - "position": { - "x": 688.7499923706055, - "y": 251.24999809265137 - }, - "data": { - "label": "integrator", - "initial_value": "", - "reset_times": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 200, - "height": 48 - }, - "selected": false, - "dragging": false - }, - { - "id": "2", - "type": "scope", - "position": { - "x": 1022.2499923706055, - "y": 252.24999809265137 - }, - "data": { - "label": "scope 2", - "labels": "", - "sampling_rate": "", - "t_wait": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 140 - } - } - ], - "edges": [ - { - "id": "e0-1", - "source": "0", - "target": "1", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e0-2", - "source": "0", - "target": "2", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e1-2", - "source": "1", - "target": "2", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - } - ], - "nodeCounter": 3, - "solverParams": { - "dt": "0.01", - "dt_min": "1e-6", - "dt_max": "1.0", - "Solver": "SSPRK22", - "tolerance_fpi": "1e-6", - "iterations_max": "100", - "log": "true", - "simulation_duration": "50.0", - "extra_params": "{}" - }, - "globalVariables": [], - "events": [ - { - "name": "my_event", - "type": "ZeroCrossingDown", - "func_evt": "def func_evt(t):\n *_, x = integrator_1()\n return 10 - x", - "func_act": "def func_act(t):\n source_0.off()", - "tolerance": "1e-8", - "id": 1754342253698 - } - ], - "pythonCode": "# Define your Python variables and functions here\n# Example:\n# my_variable = 42\n# def my_function(x):\n# return x * 2\n" -} \ No newline at end of file diff --git a/example_graphs/events_advanced.json b/example_graphs/events_advanced.json deleted file mode 100644 index 1b9ddd35..00000000 --- a/example_graphs/events_advanced.json +++ /dev/null @@ -1,377 +0,0 @@ -{ - "version": { - "pathsim_version": "0.8.2", - "pathview_version": "0.1.dev470+g017515800.d20250812" - }, - "nodes": [ - { - "id": "2", - "type": "process", - "position": { - "x": 868.2944372219196, - "y": 463.7056320088598 - }, - "data": { - "label": "process 2", - "initial_value": "", - "residence_time": "30", - "source_term": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 200, - "height": 120 - }, - "selected": false, - "dragging": false - }, - { - "id": "5", - "type": "amplifier", - "position": { - "x": 324.22187866193707, - "y": 500.1415773669528 - }, - "data": { - "label": "amplifier 5", - "gain": "-1", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 90, - "height": 80 - }, - "selected": false, - "dragging": false - }, - { - "id": "6", - "type": "scope", - "position": { - "x": 849.5352656218994, - "y": 616.3744300730544 - }, - "data": { - "label": "scope 6", - "labels": "", - "sampling_rate": "", - "t_wait": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 140 - }, - "selected": false, - "dragging": false - }, - { - "id": "7", - "type": "scope", - "position": { - "x": 884.3339278689236, - "y": 272.62551973484125 - }, - "data": { - "label": "scope 7", - "labels": "", - "sampling_rate": "", - "t_wait": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 120, - "height": 140 - }, - "selected": false, - "dragging": false - }, - { - "id": "8", - "type": "adder", - "position": { - "x": 470.494411363933, - "y": 507.51391609780273 - }, - "data": { - "label": "adder 8", - "operations": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 64, - "height": 64 - }, - "selected": false, - "dragging": false - }, - { - "id": "9", - "type": "integrator", - "position": { - "x": 600.7345026088365, - "y": 514.5712609435857 - }, - "data": { - "label": "storage", - "initial_value": "startup_inv", - "reset_times": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 200, - "height": 48 - }, - "selected": false, - "dragging": false - }, - { - "id": "10", - "type": "pulsesource", - "position": { - "x": 533.6515111182074, - "y": 340.6779400691841 - }, - "data": { - "label": "fusion rate", - "T": "", - "amplitude": "", - "duty": "", - "t_fall": "", - "t_rise": "", - "tau": "", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 206, - "height": 54 - }, - "selected": true, - "dragging": false - }, - { - "id": "12", - "type": "amplifier", - "position": { - "x": 734.4442527405984, - "y": 407.0512209610127 - }, - "data": { - "label": "amplifier 12", - "gain": "1.1", - "nodeColor": "#DDE6ED" - }, - "measured": { - "width": 90, - "height": 80 - }, - "selected": false, - "dragging": false - } - ], - "edges": [ - { - "id": "e2-6-from_inv", - "source": "2", - "target": "6", - "sourceHandle": "inv", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e5-8", - "source": "5", - "target": "8", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e2-8-from_mass_flow_rate", - "source": "2", - "target": "8", - "sourceHandle": "mass_flow_rate", - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e8-9", - "source": "8", - "target": "9", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e9-6", - "source": "9", - "target": "6", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e10-5", - "source": "10", - "target": "5", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e10-7", - "source": "10", - "target": "7", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e10-12", - "source": "10", - "target": "12", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - }, - { - "id": "e12-2", - "source": "12", - "target": "2", - "sourceHandle": null, - "targetHandle": null, - "type": "smoothstep", - "data": {}, - "style": { - "strokeWidth": 2, - "stroke": "#ECDFCC" - }, - "markerEnd": { - "type": "arrowclosed", - "width": 20, - "height": 20, - "color": "#ECDFCC" - } - } - ], - "nodeCounter": 13, - "solverParams": { - "dt": "0.01", - "dt_min": "1e-6", - "dt_max": "1.0", - "Solver": "SSPRK22", - "tolerance_fpi": "1e-6", - "iterations_max": "100", - "log": "true", - "simulation_duration": "300", - "extra_params": "{}" - }, - "globalVariables": [], - "events": [ - { - "name": "storage_empty", - "type": "ZeroCrossingDown", - "func_evt": "fun_stor_evt", - "func_act": "fun_stor_act", - "tolerance": "1e-8", - "id": 1754440495739 - }, - { - "name": "restart", - "type": "ZeroCrossingUp", - "func_evt": "func_evt_start", - "func_act": "func_act_start", - "tolerance": "1e-8", - "id": 1754440898819 - } - ], - "pythonCode": "def fun_stor_evt(t):\n *_, I = storage_9()\n return I\n\ndef fun_stor_act(t):\n fusion_rate_10.off()\n\nstartup_inv = 10\n\ndef func_evt_start(t):\n *_, I = storage_9()\n return I - startup_inv\n\ndef func_act_start(t):\n fusion_rate_10.on()\n " -} \ No newline at end of file diff --git a/index.html b/index.html index 0c589ecc..67d4631b 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,16 @@ - - - - - Vite + React - - -
- - - + + + + + + PathView + + + +
+ + + + \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index 867656b6..beea1a03 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -324,7 +324,7 @@ const DnDFlow = () => { try { // Modern approach: Use File System Access API for proper "Save As" dialog const fileHandle = await window.showSaveFilePicker({ - suggestedName: 'fuel-cycle-graph.json', + suggestedName: 'pathview_graph.json', types: [{ description: 'JSON files', accept: { @@ -1035,52 +1035,94 @@ const DnDFlow = () => { - {/* Help Button */} - +
+ {/* GitHub Link */} + { + e.target.style.backgroundColor = '#1b1f23'; + e.target.style.transform = 'translateY(-1px)'; + e.target.style.boxShadow = '0 4px 12px rgba(36, 41, 46, 0.4)'; + }} + onMouseLeave={(e) => { + e.target.style.backgroundColor = '#000000ff'; + e.target.style.transform = 'translateY(0)'; + e.target.style.boxShadow = '0 2px 6px rgba(36, 41, 46, 0.3)'; + }} + title="View on GitHub" + > + + + + + + {/* Help Button */} + +
{/* Graph Editor Tab */} diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx index b651e148..4490d4fe 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -1,18 +1,18 @@ import React, { useState } from 'react'; import { useDnD } from './DnDContext'; import { nodeCategories, getNodeDisplayName } from '../nodeConfig.js'; - + export default () => { const [_, setType] = useDnD(); const [expandedCategories, setExpandedCategories] = useState({ - 'Sources': true, + 'Sources': false, 'Processing': true, 'Math': true, 'Control': false, 'Fuel Cycle': false, 'Output': true }); - + const onDragStart = (event, nodeType) => { setType(nodeType); event.dataTransfer.effectAllowed = 'move'; @@ -39,9 +39,9 @@ export default () => { }; return categoryClasses[categoryName] || 'dndnode'; }; - + return ( -