Skip to content

Commit 9bfc073

Browse files
authored
1.2.0 release (#25)
* Release v1.2.0: Enhanced tooltips with links count, tabs in Unlinked panel Added: - Node tooltips now display "Links out" and "Links in" counts with color coding - New "Links count" tab in the Unlinked Modules panel - Configurable threshold filter to find nodes by connection count - Checkboxes to filter by "links in" or "links out" criteria Changed: - Unlinked panel now uses tabs interface (Unlinked / Links count) * Refactor: Extract HTML/CSS/JS templates to separate files - Move HTML structure to templates/index.html - Move CSS styles to templates/styles.css - Move JavaScript code to templates/main.js - Update vizualyzer.py to read and combine template files - Reduce vizualyzer.py from ~2000 to ~340 lines - Fix Connections panel positioning (now draggable like other panels) - Update CHANGELOG.md with refactoring details * Add display filters for nodes and links by type - Show/hide nodes: Modules, Classes, Functions, External - Show/hide links: Module→Module, Module→Entity, Dependencies - Filters available in the Display panel - Links are hidden when connected nodes are filtered out - Update CHANGELOG with display filters feature * Move Legend panel to the right of Controls panel * Add CSV export option for graph data * Add integration tests for CSV export functionality * Add CSV export documentation to README * Update README with new feature screenshots
1 parent afb1b4e commit 9bfc073

15 files changed

+2124
-1476
lines changed

CHANGELOG.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,49 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.2.0] - 2026-01-18
9+
10+
### Added
11+
12+
**Enhanced Tooltips**
13+
- Node tooltips now display "Links out" and "Links in" counts
14+
- Color-coded: orange for outgoing links, green for incoming links
15+
- Helps quickly understand node connectivity
16+
17+
**Links Count Panel**
18+
- New "Links count" tab in the Unlinked Modules panel
19+
- Configurable threshold filter (default: 1) to find nodes by connection count
20+
- Checkboxes to filter by "links in" or "links out" criteria
21+
- Click on any item to navigate and zoom to it on the graph
22+
- Useful for finding highly connected or isolated nodes
23+
24+
**Display Filters**
25+
- Show/hide nodes by type: Modules, Classes, Functions, External
26+
- Show/hide links by type: Module→Module, Module→Entity, Dependencies
27+
- All filters available in the expanded Display panel
28+
29+
**CSV Export**
30+
- New `--csv PATH` option to export graph data to CSV file
31+
- Columns: name, type (module/function/class/external), parent_module, full_path, links_out, links_in, lines
32+
- Example: `codegraph /path/to/code --csv output.csv`
33+
34+
### Changed
35+
36+
- Legend panel moved to the right of Controls panel (both at top-left area)
37+
- Renamed "Unlinked Modules" panel header, now uses tabs interface
38+
- "Unlinked" is now a tab showing modules with zero connections
39+
- "Links count" tab provides flexible filtering by connection count
40+
41+
### Refactored
42+
43+
**Template Extraction**
44+
- HTML, CSS, and JavaScript moved to separate files in `codegraph/templates/`
45+
- `templates/index.html` - HTML structure with placeholders
46+
- `templates/styles.css` - all CSS styles
47+
- `templates/main.js` - all JavaScript code
48+
- `vizualyzer.py` reduced from ~2000 to ~340 lines
49+
- Easier to maintain and edit frontend code separately
50+
851
## [1.1.0] - 2025-01-18
952

1053
### Added

README.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,32 @@ It is based only on lexical and syntax parsing, so it doesn't need to install al
2828

2929
![Node Information](docs/img/node_information.png)
3030

31-
**Tooltips** - Hover over any node to see details: type, parent module, full path, and connection count.
31+
**Tooltips** - Hover over any node to see details: type, parent module, full path, lines of code, and connection counts (links in/out).
32+
33+
### Links Count
34+
35+
![Links Count](docs/img/links_count.png)
36+
37+
**Links Count Panel** - Find nodes by their connection count. Filter by "links in" or "links out" with configurable threshold.
3238

3339
### Unlinked Modules
3440

3541
![Unlinked Nodes](docs/img/listing_unlinked_nodes.png)
3642

3743
**Unlinked Panel** - Shows modules with no connections. Click to navigate to them on the graph.
3844

45+
### Massive Objects Detection
46+
47+
![Massive Objects](docs/img/massive_objects_detection.png)
48+
49+
**Massive Objects Panel** - Find large code entities by lines of code. Filter by type (modules, classes, functions) with configurable threshold.
50+
51+
### Display Settings
52+
53+
![Display Settings](docs/img/graph_display_settings.png)
54+
55+
**Display Filters** - Show/hide nodes by type (Modules, Classes, Functions, External) and links by type (Module→Module, Module→Entity, Dependencies).
56+
3957
### UI Tips
4058

4159
![UI Tips](docs/img/tips_in_ui.png)
@@ -63,9 +81,27 @@ This will generate an interactive HTML visualization and open it in your browser
6381
| Option | Description |
6482
|--------|-------------|
6583
| `--output PATH` | Custom output path for HTML file (default: `./codegraph.html`) |
84+
| `--csv PATH` | Export graph data to CSV file |
6685
| `--matplotlib` | Use legacy matplotlib visualization instead of D3.js |
6786
| `-o, --object-only` | Print dependencies to console only, no visualization |
6887

88+
### CSV Export
89+
90+
Export graph data to CSV for analysis in spreadsheets or other tools:
91+
92+
```console
93+
codegraph /path/to/code --csv output.csv
94+
```
95+
96+
CSV columns:
97+
- `name` - Entity name
98+
- `type` - module / function / class / external
99+
- `parent_module` - Parent module (for functions/classes)
100+
- `full_path` - File path
101+
- `links_out` - Outgoing dependencies count
102+
- `links_in` - Incoming dependencies count
103+
- `lines` - Lines of code
104+
69105
## Changelog
70106

71107
See [CHANGELOG.md](CHANGELOG.md) for full version history.

codegraph/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.1.0"
1+
__version__ = "1.2.0"

codegraph/main.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@
3535
type=click.Path(),
3636
help="Output path for D3.js HTML file (default: ./codegraph.html)",
3737
)
38-
def cli(paths, object_only, file_path, distance, matplotlib, output):
38+
@click.option(
39+
"--csv",
40+
type=click.Path(),
41+
help="Export graph data to CSV file (specify output path)",
42+
)
43+
def cli(paths, object_only, file_path, distance, matplotlib, output, csv):
3944
"""
4045
Tool that creates a graph of code to show dependencies between code entities (methods, classes, etc.).
4146
CodeGraph does not execute code, it is based only on lex and syntax parsing.
@@ -56,6 +61,7 @@ def cli(paths, object_only, file_path, distance, matplotlib, output):
5661
distance=distance,
5762
matplotlib=matplotlib,
5863
output=output,
64+
csv=csv,
5965
)
6066
main(args)
6167

@@ -72,6 +78,10 @@ def main(args):
7278
click.echo(f" Distance {distance}: {', '.join(files)}")
7379
elif args.object_only:
7480
pprint.pprint(usage_graph)
81+
elif args.csv:
82+
import codegraph.vizualyzer as vz
83+
84+
vz.export_to_csv(usage_graph, entity_metadata=entity_metadata, output_path=args.csv)
7585
else:
7686
import codegraph.vizualyzer as vz
7787

codegraph/templates/index.html

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>CodeGraph - Interactive Visualization</title>
7+
<script src="https://d3js.org/d3.v7.min.js"></script>
8+
<style>
9+
/* STYLES_PLACEHOLDER */
10+
</style>
11+
</head>
12+
<body>
13+
<div id="graph"></div>
14+
<div class="tooltip" id="tooltip"></div>
15+
16+
<!-- Search box -->
17+
<div class="search-container">
18+
<div class="search-box">
19+
<input type="text" class="search-input" id="searchInput" placeholder="Search nodes... (Ctrl+F)" autocomplete="off">
20+
<button class="search-clear" id="searchClear">&times;</button>
21+
<div class="autocomplete-list" id="autocompleteList"></div>
22+
</div>
23+
</div>
24+
25+
<!-- Highlight info banner -->
26+
<div class="highlight-info" id="highlightInfo">
27+
<span id="highlightText">Highlighting: </span>
28+
<button id="clearHighlight">Clear (Esc)</button>
29+
</div>
30+
31+
<div class="panel controls" id="controls-panel">
32+
<div class="panel-header">
33+
<h4>Controls</h4>
34+
<button class="panel-toggle" title="Collapse"></button>
35+
</div>
36+
<div class="panel-content">
37+
<p><kbd>Ctrl+F</kbd> Search nodes</p>
38+
<p><kbd>Scroll</kbd> Zoom in/out</p>
39+
<p><kbd>Drag</kbd> on background - Pan</p>
40+
<p><kbd>Drag</kbd> on node - Pin node position</p>
41+
<p><kbd>Click</kbd> module/entity - Collapse/Expand</p>
42+
<p><kbd>Double-click</kbd> - Unpin / Focus on node</p>
43+
<p><kbd>Esc</kbd> Clear search highlight</p>
44+
</div>
45+
</div>
46+
<div class="panel legend" id="legend-panel">
47+
<div class="panel-header">
48+
<h4>Legend</h4>
49+
<button class="panel-toggle" title="Collapse"></button>
50+
</div>
51+
<div class="panel-content">
52+
<div class="legend-section">
53+
<h4>Nodes</h4>
54+
<div class="legend-item">
55+
<div class="legend-color legend-module"></div>
56+
<span>Module (.py file)</span>
57+
</div>
58+
<div class="legend-item">
59+
<div class="legend-color legend-entity"></div>
60+
<span>Entity (function/class)</span>
61+
</div>
62+
<div class="legend-item">
63+
<div class="legend-color legend-external"></div>
64+
<span>External dependency</span>
65+
</div>
66+
</div>
67+
<div class="legend-section">
68+
<h4>Links</h4>
69+
<div class="legend-item">
70+
<div class="legend-line legend-link-module"></div>
71+
<span>Module → Module</span>
72+
</div>
73+
<div class="legend-item">
74+
<div class="legend-line legend-link-entity" style="border-top: 2px dashed #009c2c; background: none; height: 0;"></div>
75+
<span>Module → Entity</span>
76+
</div>
77+
<div class="legend-item">
78+
<div class="legend-line legend-link-dep"></div>
79+
<span>Entity → Dependency</span>
80+
</div>
81+
</div>
82+
</div>
83+
</div>
84+
<div class="panel stats" id="stats">
85+
<div class="panel-header">
86+
<h4>Statistics</h4>
87+
<button class="panel-toggle" title="Collapse"></button>
88+
</div>
89+
<div class="panel-content" id="stats-content"></div>
90+
</div>
91+
<div class="panel unlinked-modules" id="unlinked-modules">
92+
<div class="panel-header">
93+
<h4>Connections</h4>
94+
<button class="panel-toggle" title="Collapse"></button>
95+
</div>
96+
<div class="panel-content">
97+
<div class="unlinked-tabs">
98+
<button class="unlinked-tab active" data-tab="unlinked-list">Unlinked <span class="count" id="unlinked-count"></span></button>
99+
<button class="unlinked-tab" data-tab="links-count-list">Links count <span class="count" id="links-count"></span></button>
100+
</div>
101+
<div id="unlinked-list" class="unlinked-tab-content active"></div>
102+
<div id="links-count-list" class="unlinked-tab-content">
103+
<div class="links-filter">
104+
<div class="filter-row">
105+
<label><input type="checkbox" id="links-in-check" checked> Links in</label>
106+
<label><input type="checkbox" id="links-out-check" checked> Links out</label>
107+
</div>
108+
<div class="filter-row">
109+
<span>More than:</span>
110+
<input type="number" id="links-threshold" value="5" min="0">
111+
</div>
112+
</div>
113+
<div id="links-count-content"></div>
114+
</div>
115+
</div>
116+
</div>
117+
<div class="panel massive-objects" id="massive-objects">
118+
<div class="panel-header">
119+
<h4>Massive Objects <span class="count" id="massive-count"></span></h4>
120+
<button class="panel-toggle" title="Collapse"></button>
121+
</div>
122+
<div class="panel-content">
123+
<div class="filters">
124+
<div class="filter-row">
125+
<label><input type="checkbox" id="filter-modules" checked> Modules</label>
126+
<label><input type="checkbox" id="filter-classes" checked> Classes</label>
127+
<label><input type="checkbox" id="filter-functions" checked> Functions</label>
128+
</div>
129+
<div class="filter-row">
130+
<span>Min lines:</span>
131+
<input type="number" id="massive-threshold" value="50" min="1">
132+
</div>
133+
</div>
134+
<ul id="massive-list"></ul>
135+
</div>
136+
</div>
137+
<div class="panel size-toggle" id="size-toggle-panel">
138+
<div class="panel-header">
139+
<h4>Display</h4>
140+
<button class="panel-toggle" title="Collapse"></button>
141+
</div>
142+
<div class="panel-content">
143+
<label>
144+
<input type="checkbox" id="size-by-code" checked>
145+
Size by lines of code
146+
</label>
147+
<div class="display-section">
148+
<h5>Show nodes</h5>
149+
<label><input type="checkbox" id="show-modules" checked> Modules</label>
150+
<label><input type="checkbox" id="show-classes" checked> Classes</label>
151+
<label><input type="checkbox" id="show-functions" checked> Functions</label>
152+
<label><input type="checkbox" id="show-external" checked> External</label>
153+
</div>
154+
<div class="display-section">
155+
<h5>Show links</h5>
156+
<label><input type="checkbox" id="show-link-module" checked> Module → Module</label>
157+
<label><input type="checkbox" id="show-link-entity" checked> Module → Entity</label>
158+
<label><input type="checkbox" id="show-link-dependency" checked> Dependencies</label>
159+
</div>
160+
</div>
161+
</div>
162+
163+
<script>
164+
const graphData = /* GRAPH_DATA_PLACEHOLDER */;
165+
166+
/* SCRIPT_PLACEHOLDER */
167+
</script>
168+
</body>
169+
</html>

0 commit comments

Comments
 (0)