UNPKG

@yolkai/nx-workspace

Version:

Extensible Dev Tools for Monorepos

162 lines (133 loc) 4.02 kB
<!DOCTYPE html> <head> <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> <script src="https://dagrejs.github.io/project/dagre-d3/latest/dagre-d3.js"></script> <style id="css"> .clusters rect { fill: #00ffd0; stroke: #000; stroke-width: 1.5px; } text { font-weight: 300; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serf; font-size: 14px; } .node rect { stroke: #000; fill: #fff; stroke-width: 1.5px; } .node ellipse { stroke: #000; fill: #fff; stroke-width: 1.5px; } g.affected > rect { stroke: red; } g.affected > ellipse { stroke: red; } g.affected > path { stroke: red; } .edgePath path { stroke: #000; stroke-width: 1.5px; } form { width: 100%; background-color: #f5f5f5; padding: 20px; } </style> </head> <script> window.projects = null; window.graph = null; window.affected = null; window.filteredProjects = window.projects; function hasPath(target, node, visited) { if (target === node) return true; for (let d of window.graph.dependencies[node]) { if (visited.indexOf(d.name) > -1) continue; if (hasPath(target, d.name, [...visited, d.name])) return true; } return false; } window.filter = function(e) { const filter = document.querySelector('#filter').value.trim(); const filteredProjects = filter.length > 0 ? filter.split(',').map(r => r.trim()) : []; const exclude = document.querySelector('#exclude').value.trim(); const excludedProjects = exclude.length > 0 ? exclude.split(',').map(r => r.trim()) : []; window.filteredProjects = window.projects.filter(p => { const filtered = filteredProjects.length > 0 ? filteredProjects.find( f => hasPath(f, p.name, []) || hasPath(p.name, f, []) ) : true; return excludedProjects.indexOf(p.name) === -1 && filtered; }); render(); return false; }; setTimeout(() => { render(); }); function render() { var g = new window.dagreD3.graphlib.Graph({ compound: true }); g.setGraph({}); g.setDefaultEdgeLabel(function() { return {}; }); window.filteredProjects.forEach(p => { if (window.filteredProjects.indexOf(p) > -1) { const shape = p.type === 'lib' ? 'ellipse' : 'rect'; const clazz = window.affected.indexOf(p.name) > -1 ? 'affected' : 'no-affected'; g.setNode(p.name, { label: p.name, shape: shape, class: clazz }); } }); Object.keys(graph.dependencies).forEach(p => { const filteredProjectNames = window.filteredProjects.map(f => f.name); graph.dependencies[p].forEach(d => { if ( filteredProjectNames.indexOf(p) > -1 && filteredProjectNames.indexOf(d.target) > -1 ) { const clazz = window.affected.indexOf(p) > -1 && window.affected.indexOf(d.target) > -1 ? 'affected' : 'no-affected'; const label = d.type === 'implicit' ? 'implicit' : d.type === 'dynamic' ? 'lazy' : undefined; g.setEdge(p, d.target, { label: label, class: clazz }); } }); }); var svg = d3.select('svg'), svgGroup = svg.append('g'); var render = new window.dagreD3.render(); render(d3.select('svg g'), g); svg.attr('height', g.graph().height + 40); svg.attr('width', g.graph().width + 100); var xCenterOffset = (svg.attr('width') - g.graph().width) / 2; svgGroup.attr('transform', 'translate(' + xCenterOffset + ', 20)'); } </script> <form onsubmit="return window.filter()"> <div> Filter <input id="filter" /> Exclude <input id="exclude" /> <button>Apply</button> </div> </form> <svg id="svg-canvas" width="1024" height="960"></svg>