aboutsummaryrefslogtreecommitdiffstats
path: root/client/src/layout.js
blob: c9c2a4d1d39f861c63322cf9e374d0b96d2a5f98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import Viz from './viz.es';

const toNumber = (i) => Number(i);
const gv = new Viz({ workerURL: 'lib/lite.render.js' });

export default class Layout {
	constructor() {
		this.src = 'digraph { node [shape="rectangle"];\n';
	}

	addNode(id, width, height) {
		this.src += `  "${id}" [fixedsize=true; width=${width / 72}; height=${height / 72}];\n`;
	}

	addLink(from, to) {
		this.src += `  "${from}" -> "${to}";\n`;
	}

	async render() {
		this.src += '}';

		const info = await gv.renderJSONObject(this.src, { format: 'json0' });
		info.objects ||= [];
		info.edges ||= [];
		const [width, height] = info.bb.split(',').map(toNumber).slice(2);

		const positions = {};
		for (const object of info.objects) {
			const [x, y] = object.pos.split(',').map(toNumber);
			positions[object.name] = [ x, height - y ];
		}

		const links = info.edges.map((edge) => {
			const pos = edge.pos.slice(2);
			return pos.split(' ').map(p => {
				const [x, y] = p.split(',');
				return [toNumber(x), height - toNumber(y)];
			});

		});

		return {
			width, height,
			positions,
			links,
		};
	}
}