Last active
June 4, 2018 11:13
-
-
Save MayaLekova/b58e3acf93a92172d7515d42ac515c4a to your computer and use it in GitHub Desktop.
Tool to draw trees out of async resource ids
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs'); | |
const D3Node = require('d3-node') | |
const d3n = new D3Node(); | |
const d3 = d3n.d3; | |
const w = 400, h = 300; | |
// Draw the contents of the 'root' hierarchy in the 'svg' element | |
function draw(root, svg) { | |
// Nodes | |
let nodes = svg | |
.selectAll('circle.node') | |
.data(root.descendants()) | |
.enter() | |
.append('g') | |
.classed('node', true); | |
nodes.append('circle') | |
.attr('cx', function(d) {return d.x;}) | |
.attr('cy', function(d) {return d.y;}) | |
.attr('r', 4); | |
nodes.append('text') | |
.text(function(d) { return d.id; }) | |
.attr('x', function(d) {return d.x + 5;}) | |
.attr('y', function(d) {return d.y;}) | |
.style('font-size', 'x-large'); | |
// Links | |
svg | |
.selectAll('line.link') | |
.data(root.links()) | |
.enter() | |
.append('line') | |
.classed('link', true) | |
.attr('x1', function(d) {return d.source.x;}) | |
.attr('y1', function(d) {return d.source.y;}) | |
.attr('x2', function(d) {return d.target.x;}) | |
.attr('y2', function(d) {return d.target.y;}) | |
.attr('style', 'stroke:lightsteelblue;stroke-width:2'); | |
} | |
// main pipeline | |
// 1. construct the hierarchy | |
// 2. layout this as a tree | |
// 3. create the SVG and draw into it | |
// 4. dump into an .svg file | |
function drawAsyncTree(parsed) { | |
let root = d3.stratify() | |
.id(function(d) { return d.id; }) | |
.parentId(function(d) { return d.parent; }) | |
(parsed); | |
d3.tree().size([w, h])(root); | |
const svg = d3n.createSVG(w,h+100).append('g') | |
.attr('transform', `translate(0,50)`); | |
draw(root, svg); | |
fs.writeFileSync('output.svg', d3n.svgString(), 'utf8'); | |
} | |
// parse children[] and parents[] arrays into a hierarchy | |
function idsParse(children, parents) { | |
let ret = []; | |
ret.push({id: 1, parent: undefined}); | |
for (let idx in children) { | |
ret.push({id: children[idx], parent: parents[idx]}); | |
} | |
return ret; | |
} | |
// Async hooks instrumentation for promises | |
const async_hooks = require('async_hooks'); | |
let asyncIds = [], triggerIds = []; | |
let ah = async_hooks.createHook({ | |
init(asyncId, type, triggerAsyncId, resource) { | |
if (type !== 'PROMISE') { | |
return; | |
} | |
asyncIds.push(asyncId); | |
triggerIds.push(triggerAsyncId); | |
}, | |
}); | |
ah.enable(); | |
// Simplified version of Node.js util.promisify(setTimeout) | |
function sleep(timeout) { | |
const promise = new Promise(function(resolve, reject) { | |
try { | |
setTimeout((err, ...values) => { | |
if (err) { | |
reject(err); | |
} else { | |
resolve(values[0]); | |
} | |
}, timeout); | |
} catch (err) { | |
reject(err); | |
} | |
}); | |
return promise; | |
} | |
// Here goes the actual async code | |
async function foo() { | |
// await sleep(10); | |
// await something or create a promise | |
} | |
foo().then(() => { | |
let parsed = idsParse(asyncIds, triggerIds); | |
drawAsyncTree(parsed); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment