Add project dependency tracking system with yEd and PNG export
- Implement @DEP_IN/OUT/RUN tag standard for MATLAB script metadata - Add buildDependencyGraph.m for full project mapping and yEd (.tgf) export - Add plotSingleFileDependencies.m and plotNodeHistory.m for targeted analysis - Standardize output naming convention to 'Dependency_*' for Finder organization - Configure high-resolution PNG export as default static fallback
This commit is contained in:
1 parent
873377ce80
commit
e5226802a3
4 files changed
+538
-40
No files matched your search
@@ -0,0 +1,151 @@
|
||||
function subG = plotSingleFileDependencies(G, targetFile)
|
||||
% PLOTSINGLEFILEDEPENDENCIES Extracts and plots the dependencies for a single file.
|
||||
%
|
||||
% USAGE:
|
||||
% G = buildDependencyGraph(); % First, get the master graph
|
||||
% plotSingleFileDependencies(G, 'FitList.mat');
|
||||
%
|
||||
% =========================================================================
|
||||
% SCRIPT OUTPUTS & VISUALIZATION OPTIONS
|
||||
% =========================================================================
|
||||
% 1. MATLAB Figure: A standard MATLAB figure window will automatically
|
||||
% open displaying the dependency graph.
|
||||
%
|
||||
% 2. Static Image (PNG): A high-resolution (300 DPI) PNG file is saved to
|
||||
% your current directory (e.g., 'ProjectDependencies.png'). This is
|
||||
% ideal for quick viewing, sharing, or inserting into reports.
|
||||
%
|
||||
% 3. Interactive Graph (yEd Graph Editor): For complex networks where you
|
||||
% can drag, auto-layout, and isolate nodes:
|
||||
% a) Find the generated text file (e.g., 'Dependency_Graph.tgf').
|
||||
% b) Open the free yEd Graph Editor app (macOS/Windows/Linux).
|
||||
% c) Go to File -> Open and select the .tgf file.
|
||||
% d) To arrange the messy graph, go to the top menu:
|
||||
% Layout -> Hierarchical (or press Cmd+Option+H).
|
||||
%
|
||||
% =========================================================================
|
||||
% =========================================================================
|
||||
% HOW TO UNTANGLE THE GRAPH IN yEd (First-time Open)
|
||||
% =========================================================================
|
||||
% When you first open the .tgf file, the nodes will be in a messy pile.
|
||||
% Follow these 3 steps to instantly format the dependency tree:
|
||||
%
|
||||
% 1. UNTANGLE: Go to Layout -> Hierarchical (or press Cmd+Option+H).
|
||||
% This arranges the scripts and data files in a logical flow.
|
||||
%
|
||||
% 2. FIX BOX SIZES: Press Cmd+A to select all, then go to:
|
||||
% Tools -> Fit Node to Label... -> Click OK.
|
||||
% This resizes the boxes to fit your file names perfectly.
|
||||
%
|
||||
% 3. VIEW ALL: Click the 'Fit Content' icon (magnifying glass with square)
|
||||
% in the top toolbar to center the graph on your screen.
|
||||
%
|
||||
% You can now click and drag any node; the arrows will follow automatically.
|
||||
% =========================================================================
|
||||
|
||||
% 1. Check if the file actually exists in the graph
|
||||
if findnode(G, targetFile) == 0
|
||||
error('File "%s" was not found in the dependency graph. Check spelling and paths.', targetFile);
|
||||
end
|
||||
|
||||
% 2. Find scripts that create it (incoming edges)
|
||||
creators = predecessors(G, targetFile);
|
||||
|
||||
% 3. Find scripts that use it (outgoing edges)
|
||||
consumers = successors(G, targetFile);
|
||||
|
||||
% 4. Combine them into a single list of nodes to keep
|
||||
neighborhood = unique([targetFile; creators; consumers]);
|
||||
|
||||
% 5. Extract the smaller subgraph
|
||||
subG = subgraph(G, neighborhood);
|
||||
|
||||
% ---------------------------------------------------------
|
||||
% 6. Apply Colors (Highlighting the Target File)
|
||||
% ---------------------------------------------------------
|
||||
numNodes = numnodes(subG);
|
||||
nodeColors = zeros(numNodes, 3);
|
||||
|
||||
colorScript = [0 0.4470 0.7410]; % Blue for .m scripts
|
||||
colorData = [0.8500 0.3250 0.0980]; % Orange for .mat data
|
||||
colorOther = [0.4660 0.6740 0.1880]; % Green for anything else
|
||||
colorTarget = [0.9290 0.6940 0.1250]; % Gold/Yellow for the TARGET file
|
||||
|
||||
for n = 1:numNodes
|
||||
nodeName = subG.Nodes.Name{n};
|
||||
if strcmp(nodeName, targetFile)
|
||||
nodeColors(n, :) = colorTarget; % Apply Gold to target
|
||||
elseif endsWith(nodeName, '.m', 'IgnoreCase', true)
|
||||
nodeColors(n, :) = colorScript;
|
||||
elseif endsWith(nodeName, '.mat', 'IgnoreCase', true)
|
||||
nodeColors(n, :) = colorData;
|
||||
else
|
||||
nodeColors(n, :) = colorOther;
|
||||
end
|
||||
end
|
||||
|
||||
% ---------------------------------------------------------
|
||||
% 7. Plot the Subgraph
|
||||
% ---------------------------------------------------------
|
||||
fig = figure('Name', ['Dependencies for ' targetFile], 'Color', 'w');
|
||||
p = plot(subG, 'Layout', 'layered', ...
|
||||
'NodeLabel', subG.Nodes.Name, ...
|
||||
'Interpreter', 'none', ...
|
||||
'NodeColor', nodeColors, ...
|
||||
'MarkerSize', 8, ...
|
||||
'EdgeColor', [0.7 0.7 0.7], ...
|
||||
'LineWidth', 1.5, ...
|
||||
'ArrowSize', 12);
|
||||
|
||||
% Make the target file visually stand out by making its marker larger
|
||||
highlight(p, targetFile, 'MarkerSize', 14);
|
||||
|
||||
p.NodeFontSize = 10;
|
||||
p.NodeFontWeight = 'bold';
|
||||
title(['Data Flow for: ' targetFile], 'Interpreter', 'none');
|
||||
|
||||
% ---------------------------------------------------------
|
||||
% 8. Export Data
|
||||
% ---------------------------------------------------------
|
||||
safeName = strrep(targetFile, '/', '_');
|
||||
safeName = strrep(safeName, '\', '_');
|
||||
% Use the new consistent prefix
|
||||
outputFile = sprintf('Dependency_Node_%s.png', safeName);
|
||||
|
||||
|
||||
% --- Export text for yEd Graph Editor (TGF Format) ---
|
||||
if numedges(subG) > 0
|
||||
% Extract the exact edges from the subgraph
|
||||
subSources = subG.Edges.EndNodes(:,1);
|
||||
subTargets = subG.Edges.EndNodes(:,2);
|
||||
|
||||
% 1. Create a unique list of all nodes in this subgraph
|
||||
allNodes = unique([subSources; subTargets; targetFile]);
|
||||
|
||||
safeName = strrep(targetFile, '/', '_');
|
||||
safeName = strrep(safeName, '\', '_');
|
||||
tgfFile = sprintf('Dependency_Node_%s.tgf', safeName);
|
||||
fid = fopen(tgfFile, 'w');
|
||||
|
||||
% 2. Write the Node List (Format: ID Label)
|
||||
for i = 1:length(allNodes)
|
||||
fprintf(fid, '%d %s\n', i, allNodes{i});
|
||||
end
|
||||
|
||||
% 3. Write the Separator
|
||||
fprintf(fid, '#\n');
|
||||
|
||||
% 4. Write the Edge List (Format: SourceID TargetID)
|
||||
for i = 1:length(subSources)
|
||||
srcIdx = find(strcmp(allNodes, subSources{i}));
|
||||
tgtIdx = find(strcmp(allNodes, subTargets{i}));
|
||||
fprintf(fid, '%d %d\n', srcIdx, tgtIdx);
|
||||
end
|
||||
|
||||
fclose(fid);
|
||||
fprintf('Generated %s for yEd Graph Editor.\n', tgfFile);
|
||||
end
|
||||
% --- Export high-res PNG ---
|
||||
exportgraphics(fig, outputFile, 'Resolution', 300, 'BackgroundColor', 'w');
|
||||
fprintf('Saved isolated dependency graph to %s\n', outputFile);
|
||||
end
|
||||
Reference in new issue
Block a user