Files
nappMATLAB-toolbox/utils/plotNodeHistory.m
T
bartels-rausch e5226802a3 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
2026-04-02 10:56:28 +02:00

152 lines
6.3 KiB
Matlab

function historyG = plotNodeHistory(G, targetFile)
% PLOTNODEHISTORY Extracts and plots the entire upstream history for a single file.
%
% USAGE:
% G = buildDependencyGraph();
% plotNodeHistory(G, 'Results/FinalPlot.fig');
%
% =========================================================================
% 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.', targetFile);
end
% 2. Reverse the graph's arrows to walk backwards up the chain
revG = flipedge(G);
% 3. Use Breadth-First Search to find all "ancestors" (upstream nodes)
% This returns the target file itself plus everything that leads to it.
ancestors = bfsearch(revG, targetFile);
% 4. Extract the historical subgraph from the ORIGINAL graph
historyG = subgraph(G, ancestors);
% ---------------------------------------------------------
% 5. Apply Colors
% ---------------------------------------------------------
numNodes = numnodes(historyG);
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
colorFig = [0.4940 0.1840 0.5560]; % Purple for figures (.fig, .png, etc.)
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 = historyG.Nodes.Name{n};
if strcmp(nodeName, targetFile)
nodeColors(n, :) = colorTarget;
elseif endsWith(nodeName, '.m', 'IgnoreCase', true)
nodeColors(n, :) = colorScript;
elseif endsWith(nodeName, '.mat', 'IgnoreCase', true)
nodeColors(n, :) = colorData;
elseif endsWith(nodeName, {'.fig', '.png', '.svg', '.pdf'}, 'IgnoreCase', true)
nodeColors(n, :) = colorFig;
else
nodeColors(n, :) = colorOther;
end
end
% ---------------------------------------------------------
% 6. Plot the History Graph
% ---------------------------------------------------------
fig = figure('Name', ['History for ' targetFile], 'Color', 'w');
p = plot(historyG, 'Layout', 'layered', ...
'NodeLabel', historyG.Nodes.Name, ...
'Interpreter', 'none', ...
'NodeColor', nodeColors, ...
'MarkerSize', 8, ...
'EdgeColor', [0.7 0.7 0.7], ...
'LineWidth', 1.5, ...
'ArrowSize', 12);
% Highlight the target file
highlight(p, targetFile, 'MarkerSize', 14);
p.NodeFontSize = 10;
p.NodeFontWeight = 'bold';
title(['Full Provenance Chain for: ' targetFile], 'Interpreter', 'none');
% ---------------------------------------------------------
% 7. Export Data
% ---------------------------------------------------------
safeName = strrep(targetFile, '/', '_');
safeName = strrep(safeName, '\', '_');
outputFile = sprintf('Dependency_History_%s.png', safeName);
% --- Export text for yEd Graph Editor (TGF Format) ---
if numedges(historyG) > 0
% Extract the exact edges from the history subgraph
histSources = historyG.Edges.EndNodes(:,1);
histTargets = historyG.Edges.EndNodes(:,2);
% 1. Create a unique list of all nodes in this history graph
allNodes = unique([histSources; histTargets; targetFile]);
safeName = strrep(targetFile, '/', '_');
safeName = strrep(safeName, '\', '_');
tgfFile = sprintf('Dependency_History_%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(histSources)
srcIdx = find(strcmp(allNodes, histSources{i}));
tgtIdx = find(strcmp(allNodes, histTargets{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 full history graph to %s\n', outputFile);
end