Skip to content

Commit 2daecc1

Browse files
aksOpsclaude
andcommitted
Replace Mermaid with Cytoscape.js for interactive flow visualization
- Dropped Mermaid in favor of Cytoscape.js with dagre layout - Interactive zoom/pan/click with node detail panel - Bundled vendor JS inline for offline/corporate firewall use - Added project name (scanned directory) to header - View switching, zoom controls, fit-to-screen - All 1,662 tests passing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a5f1002 commit 2daecc1

9 files changed

Lines changed: 4081 additions & 137 deletions

File tree

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ code-intelligence = "code_intelligence.cli:app"
4040
[tool.setuptools.packages.find]
4141
where = ["src"]
4242

43+
[tool.setuptools.package-data]
44+
code_intelligence = ["flow/templates/*.html", "flow/vendor/*.js"]
45+
4346
[tool.pytest.ini_options]
4447
testpaths = ["tests"]
4548
pythonpath = ["src"]

src/code_intelligence/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ def flow(
666666
engine = FlowEngine(store)
667667

668668
if format == "html":
669-
content = engine.render_interactive()
669+
content = engine.render_interactive(project_name=path.resolve().name)
670670
out_path = output or Path("flow.html")
671671
out_path.write_text(content)
672672
console.print(f"Interactive flow diagram saved to [bold]{out_path}[/bold]")

src/code_intelligence/flow/engine.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ def render(self, diagram: FlowDiagram, format: str = "mermaid") -> str:
6868
else:
6969
raise ValueError(f"Unknown format: {format}. Available: mermaid, json")
7070

71-
def render_interactive(self) -> str:
71+
def render_interactive(self, project_name: str = "Project") -> str:
7272
"""Generate all views and bake into a self-contained interactive HTML file."""
7373
all_views = self.generate_all()
7474
stats = {
7575
"total_nodes": self._store.node_count,
7676
"total_edges": self._store.edge_count,
7777
}
78-
return render_html(all_views, stats)
78+
return render_html(all_views, stats, project_name=project_name)

src/code_intelligence/flow/renderer.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,21 +101,27 @@ def render_json(diagram: FlowDiagram) -> str:
101101
return json.dumps(diagram.to_dict(), indent=2)
102102

103103

104-
def render_html(views: dict[str, FlowDiagram], stats: dict[str, Any]) -> str:
104+
def render_html(views: dict[str, FlowDiagram], stats: dict[str, Any], project_name: str = "Project") -> str:
105105
"""Render all views into a self-contained interactive HTML file."""
106-
# Generate Mermaid strings for each view
107-
views_mermaid = {}
108106
views_data = {}
109107
for name, diagram in sorted(views.items()):
110-
views_mermaid[name] = render_mermaid(diagram)
111108
views_data[name] = diagram.to_dict()
112109

113110
template_path = Path(__file__).parent / "templates" / "interactive.html"
114111
template = template_path.read_text()
115112

116-
# Inject data
117-
html = template.replace("{{VIEWS_MERMAID}}", json.dumps(views_mermaid, indent=2))
118-
html = html.replace("{{VIEWS_DATA}}", json.dumps(views_data, indent=2))
113+
# Inline vendor JS for offline/firewall use
114+
vendor_dir = Path(__file__).parent / "vendor"
115+
for placeholder, filename in [
116+
("{{VENDOR_DAGRE}}", "dagre.min.js"),
117+
("{{VENDOR_CYTOSCAPE}}", "cytoscape.min.js"),
118+
("{{VENDOR_CYTOSCAPE_DAGRE}}", "cytoscape-dagre.min.js"),
119+
]:
120+
vendor_path = vendor_dir / filename
121+
template = template.replace(placeholder, vendor_path.read_text())
122+
123+
html = template.replace("{{VIEWS_DATA}}", json.dumps(views_data, indent=2))
119124
html = html.replace("{{STATS}}", json.dumps(stats, indent=2))
125+
html = html.replace("{{PROJECT_NAME}}", json.dumps(project_name))
120126

121127
return html

src/code_intelligence/flow/templates/interactive.html

Lines changed: 212 additions & 126 deletions
Large diffs are not rendered by default.

src/code_intelligence/flow/vendor/cytoscape-dagre.min.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/code_intelligence/flow/vendor/cytoscape.min.js

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)