import { applyTableStyles, makeSortable } from '../ui/table.js'; import { createTimeRangeSelector, filterHistoryByTimeRange } from '../ui/timerange.js'; export function showNodeAnalytics(element, stats) { const { container: rangeSelector, select: timeSelect } = createTimeRangeSelector(); function updateContent() { // Filter history by time range const history = filterHistoryByTimeRange(stats.history || [], timeSelect.value); // Calculate node averages from filtered history const nodeAverages = {}; history.forEach(run => { const nodes = Object.values(run.nodes); nodes.forEach(node => { const nodeType = node.nodeType; if (!nodeAverages[nodeType]) { nodeAverages[nodeType] = { total_time: 0, vram_usage: 0, ram_usage: 0, count: 0, cache_hits: 0 }; } const stats = nodeAverages[nodeType]; stats.count++; stats.total_time = (stats.total_time * (stats.count - 1) + (node.endTime - node.startTime)) / stats.count; stats.vram_usage = (stats.vram_usage * (stats.count - 1) + (node.vramAfter - node.vramBefore)) / stats.count; stats.ram_usage = (stats.ram_usage * (stats.count - 1) + (node.ramAfter - node.ramBefore)) / stats.count; if (node.cacheHit) stats.cache_hits++; }); }); // Convert to array for sorting const nodeStats = Object.entries(nodeAverages).map(([nodeType, stats]) => ({ nodeType, ...stats })); // Sort by execution time by default nodeStats.sort((a, b) => b.total_time - a.total_time); const contentDiv = element.querySelector('.node-analytics-content'); if (!contentDiv) return; const html = [`
| Node Type | Avg Time (s) | Avg VRAM (GB) | Runs | Cache Hit % |
|---|---|---|---|---|
| ${node.nodeType} | ${avgTime}s | ${avgVram}GB | ${node.count} | ${cacheHitRate}% |