UNPKG

d3-dag

Version:

Layout algorithms for visualizing directed acylic graphs.

48 lines (43 loc) 1.5 kB
// Verify that a dag meets all criteria for validity // Note, this is written such that root must be a dummy node, i.e. have an undefined id export default function(root) { // Test that dummy criteria is met if (root.id !== undefined) throw new Error("invalid format for verification"); // Test that there are roots if (!root.children.length) throw new Error("no roots"); // Test that dag is free of cycles const seen = {}; const past = {}; let rec = undefined; function visit(node) { if (seen[node.id]) { return false; } else if (past[node.id]) { rec = node.id; return [node.id]; } else { past[node.id] = true; let result = node.children.reduce((chain, c) => chain || visit(c), false); delete past[node.id]; seen[node.id] = true; if (result && rec) result.push(node.id); if (rec === node.id) rec = undefined; return result; } } const msg = root.id === undefined ? root.children.reduce((msg, r) => msg || visit(r), false) : visit(root); if (msg) throw new Error("dag contained a cycle: " + msg.reverse().join(" -> ")); // Test that all nodes are valid root.each((node) => { if (node.id.indexOf("\0") >= 0) throw new Error("node id contained null character"); if (!node.data) throw new Error("node contained falsy data"); }); // Test that all link data is valid if (root.links().some(({ data }) => !data)) throw new Error("dag had falsy link data"); }