{"id":41126078,"url":"https://github.com/dalager/graphedexcel","last_synced_at":"2026-01-22T18:02:53.670Z","repository":{"id":257580768,"uuid":"858700670","full_name":"dalager/graphedexcel","owner":"dalager","description":"Tool to analyze and visualize dependencies between cells in Excel spreadsheets","archived":false,"fork":false,"pushed_at":"2025-11-25T15:13:55.000Z","size":28465,"stargazers_count":1,"open_issues_count":4,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-30T22:50:39.935Z","etag":null,"topics":["datavisualization","excel","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dalager.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-17T11:36:56.000Z","updated_at":"2025-11-15T09:11:31.000Z","dependencies_parsed_at":"2024-09-17T14:45:36.596Z","dependency_job_id":"06b7e38c-9592-49f4-8351-f12fc23e2fc5","html_url":"https://github.com/dalager/graphedexcel","commit_stats":null,"previous_names":["dalager/graphedexcel"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/dalager/graphedexcel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dalager%2Fgraphedexcel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dalager%2Fgraphedexcel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dalager%2Fgraphedexcel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dalager%2Fgraphedexcel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dalager","download_url":"https://codeload.github.com/dalager/graphedexcel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dalager%2Fgraphedexcel/sbom","scorecard":{"id":1239758,"data":{"date":"2025-11-15T09:11:40Z","repo":{"name":"github.com/dalager/graphedexcel","commit":"e83bdfb52d7146995638416604af63830213043c"},"scorecard":{"version":"v5.3.0","commit":"c22063e786c11f9dd714d777a687ff7c4599b600"},"score":8.3,"checks":[{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dependency-update-tool"}},{"name":"Code-Review","score":-1,"reason":"Found no human activity in the last 30 changesets","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#security-policy"}},{"name":"Maintained","score":5,"reason":"6 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:27","Info: jobLevel 'packages' permission set to 'read': .github/workflows/codeql.yml:23","Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:26","Info: jobLevel 'contents' permission set to 'read': .github/workflows/docker-build-push.yml:17","Info: jobLevel 'contents' permission set to 'read': .github/workflows/docker-build.yml:16","Info: jobLevel 'contents' permission set to 'read': .github/workflows/python-app.yml:15","Warn: jobLevel 'security-events' permission set to 'write': .github/workflows/python-app.yml:16","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/dependency-review.yml:13","Info: topLevel 'contents' permission set to 'read': .github/workflows/docker-build-push.yml:9","Info: topLevel 'contents' permission set to 'read': .github/workflows/docker-build.yml:10","Info: topLevel 'contents' permission set to 'read': .github/workflows/pypi-publish.yml:8","Info: topLevel 'contents' permission set to 'read': .github/workflows/python-app.yml:10","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:18"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info:  20 out of  20 GitHub-owned GitHubAction dependencies pinned","Info:   5 out of   5 third-party GitHubAction dependencies pinned","Info:   2 out of   2 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":5,"reason":"badge detected: Passing","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: SAST configuration detected: CodeQL","Info: all commits (30) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#sast"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#fuzzing"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/docker-build-push.yml:13"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":4,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Info: 'branch protection settings apply to administrators' is required to merge on branch 'main'","Info: 'stale review dismissal' is required to merge on branch 'main'","Warn: branch 'main' does not require approvers","Warn: codeowners review is required - but no codeowners file found in repo","Warn: 'last push approval' is disabled on branch 'main'","Info: 'up-to-date branches' is required to merge on branch 'main'","Info: status check found to merge onto on branch 'main'","Info: PRs are required in order to make changes on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#branch-protection"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#license"}},{"name":"Contributors","score":6,"reason":"project has 2 contributing companies or organizations -- score normalized to 6","details":["Info: found contributions from: eksponent, eksponent aps"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"30 out of 30 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#ci-tests"}}]},"last_synced_at":"2025-11-15T11:22:19.859Z","repository_id":257580768,"created_at":"2025-11-15T11:22:19.859Z","updated_at":"2025-11-15T11:22:19.859Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28667881,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T17:07:18.858Z","status":"ssl_error","status_checked_at":"2026-01-22T17:05:02.040Z","response_time":144,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["datavisualization","excel","python"],"created_at":"2026-01-22T18:02:34.726Z","updated_at":"2026-01-22T18:02:53.643Z","avatar_url":"https://github.com/dalager.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Graphedexcel\n\n[![current release version](https://img.shields.io/github/release/dalager/graphedexcel.svg?style=flat-square)](https://github.com/dalager/graphedexcel/releases)\n[![pypi version](https://img.shields.io/pypi/v/graphedexcel.svg?style=flat-square)](https://pypi.python.org/pypi/graphedexcel)\n![Python Version](https://img.shields.io/badge/python-3.10%3A3.13-blue?style=flat-square)\n[![codecov](https://codecov.io/github/dalager/graphedexcel/branch/main/graph/badge.svg?token=CJM0EAUF9M)](https://codecov.io/github/dalager/graphedexcel)\n[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9620/badge)](https://www.bestpractices.dev/projects/9620)\n\n\u003cimg src=\"docs/images/Book1.xlsx.png\" align=\"right\" width=\"300\" alt=\"Plot from Example Book1.xlsx file\"\u003e\n\n## Overview\n\nGraphedexcel takes an Excel file and creates a graph data structure with a visual representation.\n\n\u003cbr clear=\"right\"/\u003e\n\n## Usage\n\nGraphedExcel can be used in three ways:\n\n1. As a Python CLI tool, installed from PyPi with `pip install graphedexcel` (requires Python)\n2. As a Docker container, `ghcr.io/dalager/graphedexcel`, exposing the CLI tool, not requiring any python dependencies being installed. (Requires Docker)\n3. As a Python module used within your own code, by importing the `graphedexcel` module. (Requires Python and some python programming experience)\n\n### CLI Tool\n\n```bash\n# Install it\npip install graphedexcel\n# Run it\npython -m graphedexcel \u003cpath_to_excel_file\u003e\n```\n\nSee the command line options below.\n\n### Docker\n\nGraphedExcel is published to \u003chttps://ghcr.io/dalager/graphedexcel\u003e and can be run with the following command:\n\n```bash\ndocker run -v $(pwd):/data ghcr.io/dalager/graphedexcel /data/myworkbook.xlsx -o /data/myworkbook.png\n```\n\nWhere `myworkbook.xlsx` is sitting in the current directory and the output image will be saved as `myworkbook.png`, also in the current directory.\n\nThe `-v` flag is used to mount the current directory into the container as `/data/`\n\nFor powershell, use `${pwd}` instead of `$(pwd)` to get the current directory.\n\n### Python Module\n\n```python\nimport graphedexcel as ge\n\ngraph,stats = ge.graphbuilder.build_graph_and_stats(\"Book1.xlsx\")\nge.graph_summarizer.print_summary(graph, stats)\nge.graph_visualizer.visualize_dependency_graph(graph)\n\n```\n\n## Definitions\n\nSingle-cell references in a formula sitting in cell `A3` like `=A1+A2` is considered a dependency between the node `A3` and the nodes `A2` and `A1`.\n\n```mermaid\ngraph TD\n    A3 --\u003e A1\n    A3 --\u003e A2\n    A3[\"A3=A1+A2\"]\n```\n\nA range defined in a formula like `=SUM(B1:B3)` is kept as a single node in the graph, but all the containing cells are expanded as dependencies of the range node.\n\nSo when a cell, `C1` contains `=SUM(B1:B3)` the graph will look like this:\n\n```mermaid\n\ngraph TD\n    R --\u003e B1\n    R --\u003e B2\n    R --\u003e B3\n    R[\"B1:B3\"]\n    C1 --\u003e R\n\n    C1[\"C1=SUM(B1:B3)\"]\n\n```\n\n## Build and run from source\n\n### Prerequisites\n\n- Python 3.10 or later\n- Poetry (\u003chttps://python-poetry.org/\u003e)\n\n```bash\npoetry install\npoetry run graphedexcel \u003cpath_to_excel_file\u003e [options]\n```\n\n## Using the CLI tool and its varous options\n\n```bash\npython -m graphedexcel \u003cpath_to_excel_file\u003e\n```\n\n### Parameters from `--help`\n\n```\nusage: graphedexcel [-h] [--as-directed-graph] [--no-visualize]\n                    [--layout {spring,circular,kamada_kawai,shell,spectral}]\n                    [--config CONFIG] [--output-path OUTPUT_PATH]\n                    [--open-image]\n                    path_to_excel\n\nProcess an Excel file to build and visualize dependency graphs.\n\npositional arguments:\n  path_to_excel         Path to the Excel file to process.\n\noptions:\n  -h, --help            show this help message and exit\n  --as-directed-graph, -d\n                        Treat the dependency graph as directed.\n  --no-visualize, -n    Skip the visualization of the dependency\n                        graph.\n  --layout, -l {spring,circular,kamada_kawai,shell,spectral}\n                        Layout algorithm for graph visualization\n                        (default: spring).\n  --config, -c CONFIG   Path to the configuration file for\n                        visualization. See README for details.\n  --output-path, -o OUTPUT_PATH\n                        Specify the output path for the generated\n                        graph image.\n  --open-image          Open the generated image after visualization.\n  --hide-legends        Do not show legends in the visualization. (Default: False)\n```\n\n## Sample output\n\nThe following is the output of running the script on the sample `docs/Book1.xlsx` file.\n\n```bash\n===  Dependency Graph Summary ===\nCell/Node count                70\nDependency count              100\n\n\n===  Most connected nodes     ===\nRange Madness!A2:A11           22\nRange Madness!B2:B11           11\nRange Madness!F1               10\nMain Sheet!B5                   4\nMain Sheet!B22                  4\nDetached !A2:A4                 4\nRange Madness!B2                4\nRange Madness!B3                4\nRange Madness!B4                4\nRange Madness!B5                4\n\n===  Most used functions      ===\nSUM                             4\nPOWER                           1\n\nVisualizing the graph of dependencies.\nThis might take a while...\n\nGraph visualization saved to images/.\\Book1.xlsx.png\n```\n\n## Sample plot\n\nMore in `docs/images` folder.\n\n![Sample graph](docs/images/simplified_1.xlsx5.png)\n\n## Customizing Graph Visualization Settings\n\nYou can customize the graph visualization settings by passing a path to a JSON configuration file. This allows you to override the default settings with your own preferences.\n\nLook at \u003chttps://networkx.org/documentation/stable/reference/generated/networkx.drawing.nx_pylab.draw_networkx.html\u003e for the available settings.\n\n### Default Settings\n\nThe default settings for the graph visualization in the various sizes (from `graph_visualizer.py`):\n\n```python\n# Default settings for the graph visualization\nbase_graph_settings = {\n    \"node_size\": 50,        # the size of the node\n    \"width\": 0.2,           # the width of the edge between nodes\n    \"edge_color\": \"black\",  # the color of the edge between nodes\n    \"linewidths\": 0,        # the stroke width of the node border\n    \"with_labels\": False,   # whether to show the node labels\n    \"font_size\": 10,        # the size of the node labels\n    \"cmap\": \"tab20b\",       # the color map to use for coloring nodes\n    \"fig_size\": (10, 10),   # the size of the figure\n}\n\n# Sized-based settings for small, medium, and large graphs\nsmall_graph_settings = {\n    \"with_labels\": False,\n    \"alpha\": 0.8}\n\nmedium_graph_settings = {\n    \"node_size\": 30,\n    \"with_labels\": False,\n    \"alpha\": 0.4,\n    \"fig_size\": (20, 20),\n}\n\nlarge_graph_settings = {\n    \"node_size\": 20,\n    \"with_labels\": False,\n    \"alpha\": 0.2,\n    \"fig_size\": (25, 25),\n}\n\n```\n\n### Custom JSON Configuration\n\nTo override these settings, create a JSON file (e.g., graph_settings.json) with the desired settings. Here is an example of a JSON configuration file:\n\n```json\n{\n  \"node_size\": 40,\n  \"edge_color\": \"blue\",\n  \"with_labels\": true,\n  \"font_size\": 12,\n  \"alpha\": 0.6\n}\n```\n\n### Using the Custom Configuration\n\nTo use the custom configuration, pass the path to the JSON file as an argument to the script:\n\n```bash\npython -m graphedexcel myexcel.xlsx --config graph_settings.json\n```\n\nThis will render the graph using the custom settings defined in the JSON file.\n\n## Tests\n\nJust run pytest in the root folder.\n\n```bash\npoetry run pytest\n```\n\n### Bandit Security Tests\n\nTo run the Bandit (\u003chttps://github.com/PyCQA/bandit\u003e) security tests, you can use the following command.\nIt will report on medium and high severity safety issues.\n\n```bash\npoetry run bandit -c pyproject.toml -r . -lll\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdalager%2Fgraphedexcel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdalager%2Fgraphedexcel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdalager%2Fgraphedexcel/lists"}