@yolkai/nx-workspace
Version:
162 lines (133 loc) • 4.02 kB
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>