├── CNAME ├── .gitignore ├── requirements-dev.txt ├── python ├── pydot-1.4.1-py2.py3-none-any.whl ├── rcviz_test.py └── rcviz.py ├── package.json ├── .github ├── workflows │ ├── javascript.yaml │ └── python.yaml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── pull_request_template.md └── code_of_conduct.md ├── pyproject.toml ├── README.md ├── old ├── hanoi.html ├── vis.css ├── count_stair_ways4.json ├── find_zero_binary.json ├── tree.html ├── index.html ├── fib5.json ├── simple_tree.json ├── fib4.json ├── make_gasket1.json ├── count_k.json ├── tree.js ├── num_partitions63.json ├── vis.js └── make_gasket2.json ├── css └── recursive_tree_viz.css ├── javascript └── recursive_tree_viz.js ├── index.html ├── eslint.config.mjs ├── rendered ├── sprout_leaves1.html ├── sprout_leaves2.html ├── fact3.html ├── fib5.html └── virfib5.html └── LICENSE /CNAME: -------------------------------------------------------------------------------- 1 | www.recursionvisualizer.com -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | __pycache__ 3 | .coverage 4 | venv/ 5 | .venv/ 6 | node_modules 7 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pydot 2 | pytest==7.1.2 3 | black==22.3.0 4 | flake8==4.0.1 5 | coverage==6.4.1 6 | pytest-cov==3.0.0 7 | -------------------------------------------------------------------------------- /python/pydot-1.4.1-py2.py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pamelafox/recursive-visualizations/HEAD/python/pydot-1.4.1-py2.py3-none-any.whl -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "eslint": "^9.8.0", 4 | "@eslint/eslintrc": "^3.1.0", 5 | "@eslint/js": "^9.8.0", 6 | "globals": "^15.9.0" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.github/workflows/javascript.yaml: -------------------------------------------------------------------------------- 1 | name: Javascript checks 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - name: Install ESLint 12 | run: npm install 13 | - name: Run ESLint 14 | run: npx eslint javascript/ -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 100 3 | target-version = ['py39'] 4 | 5 | [tool.pytest.ini_options] 6 | addopts = "-ra --cov" 7 | testpaths = [ 8 | "python" 9 | ] 10 | pythonpath = ['python'] 11 | 12 | [tool.coverage.paths] 13 | source = ["python"] 14 | 15 | [tool.coverage.report] 16 | show_missing = true 17 | fail_under = 100 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # recursive-visualizations 2 | 3 | A way to visualize the call graph of recursive functions. 4 | 5 | Uses Pyodide to run rcviz.py and then a WASM PyDot/GraphViz port to build an SVG graph. 6 | Finally, some JavaScript adds a slider for stepping through the calls. 7 | 8 | To run locally: 9 | 10 | ```python3 -m http.server``` 11 | 12 | To run Python tests: 13 | 14 | ```pytest``` 15 | -------------------------------------------------------------------------------- /old/hanoi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |You can move a disk by clicking it, dragging it over to the desired peg, and releasing it.
9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /old/vis.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, sans-serif; 3 | } 4 | 5 | .node { 6 | background: white; 7 | border: 2px solid #ccc; 8 | color: #757575; 9 | border-radius: 120px; 10 | position: absolute; 11 | left: 0; 12 | width: 50px; 13 | height: 25px; 14 | text-align: center; 15 | font-family: monospace; 16 | padding: 10px 10px 0px 10px; 17 | z-index: 1; 18 | } 19 | 20 | 21 | .node-activated { 22 | color: #12bf96; 23 | border: 2px solid #12bf96; 24 | } 25 | 26 | .jtk-connector { 27 | z-index: 0; 28 | 29 | } 30 | 31 | .jtk-connector-activated { 32 | z-index: 0; 33 | color: turquoise; 34 | } 35 | 36 | input[type=range] { 37 | vertical-align:middle; 38 | } 39 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### High-level description of change 2 | 3 | 4 | ### Have you added tests to cover this new/updated code? 5 | 6 | _REPLACE THIS: Remember to check the code coverage report for 100% coverage of your new code, or note if it's not needed_ 7 | 8 | ### Risks involved 9 | 10 | _REPLACE THIS: Note anything that could go wrong. Good opportunity to think through edge cases_ 11 | 12 | ### Are there any dependencies or blockers for merging this? 13 | 14 | _REPLACE THIS: Note any branches that must be merged elsewhere, e.g._ 15 | 16 | ### How can we immediately test that it works? 17 | 18 | _REPLACE THIS: Describe how we can check this change works from end to end, like test function code and a screenshot of expected output._ 19 | -------------------------------------------------------------------------------- /old/count_stair_ways4.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "count_stair_ways(4)", 3 | "id": "0x7fdf3548a240->0x7fdf35061440", 4 | "children": [ 5 | { 6 | "label": "count_stair_ways(3)", 7 | "id": "0x7fdf3530d3d0->0x7fdf3548a240->0x7fdf35061440", 8 | "children": [ 9 | { 10 | "label": "count_stair_ways(2)", 11 | "id": "0x7fdf335cddc0->0x7fdf3530d3d0->0x7fdf3548a240->0x7fdf35061440", 12 | "children": [] 13 | }, 14 | { 15 | "label": "count_stair_ways(1)", 16 | "id": "0x7fdf335cddc0->0x7fdf3530d3d0->0x7fdf3548a240->0x7fdf35061440", 17 | "children": [] 18 | } 19 | ] 20 | }, 21 | { 22 | "label": "count_stair_ways(2)", 23 | "id": "0x7fdf335cddc0->0x7fdf3548a240->0x7fdf35061440", 24 | "children": [] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /css/recursive_tree_viz.css: -------------------------------------------------------------------------------- 1 | .graph .node, .graph .edge, .graph .node text { 2 | visibility: hidden; 3 | } 4 | .graph .node.activated text:first-of-type { 5 | visibility: visible; 6 | } 7 | .graph .node.activated path { 8 | visibility: visible; 9 | } 10 | .graph .node text.activated { 11 | visibility: visible; 12 | } 13 | .graph .edge.activated { 14 | visibility: visible; 15 | } 16 | .svg-controls { 17 | width: 600px; 18 | display: grid; 19 | grid-template-rows: 1fr; 20 | grid-template-columns: 100px 1fr 100px; 21 | grid-gap: 8px; 22 | background: #80808070; 23 | } 24 | .svg-controls button:first-of-type { 25 | grid-row: 1; 26 | grid-column: 1; 27 | } 28 | .svg-controls input { 29 | grid-row: 1; 30 | grid-column: 2; 31 | } 32 | .svg-controls button:last-of-type { 33 | grid-row: 1; 34 | grid-column: 3; 35 | } -------------------------------------------------------------------------------- /old/find_zero_binary.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "find_zero(1, 20,👋🏻 Are you comfortable publicly sharing your visualizations? I'd love to see how folks are using this tool. 112 | Post a link in the discussions 113 | or @ me on social media (Twitter, Mastodon) 114 |
115 |Source code on Github. Thank you @carlsborg for the rcviz library.
116 |