-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
TreeLinks.js
62 lines (51 loc) · 1.74 KB
/
TreeLinks.js
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import {ingest, tupleid, Transform} from 'vega-dataflow';
import {error, inherits} from 'vega-util';
/**
* Generate tuples representing links between tree nodes.
* The resulting tuples will contain 'source' and 'target' fields,
* which point to parent and child node tuples, respectively.
* @constructor
* @param {object} params - The parameters for this operator.
*/
export default function TreeLinks(params) {
Transform.call(this, [], params);
}
TreeLinks.Definition = {
"type": "TreeLinks",
"metadata": {"tree": true, "generates": true, "changes": true},
"params": []
};
var prototype = inherits(TreeLinks, Transform);
prototype.transform = function(_, pulse) {
var links = this.value,
tree = pulse.source && pulse.source.root,
out = pulse.fork(pulse.NO_SOURCE),
lut = {};
if (!tree) error('TreeLinks transform requires a tree data source.');
if (pulse.changed(pulse.ADD_REM)) {
// remove previous links
out.rem = links;
// build lookup table of valid tuples
pulse.visit(pulse.SOURCE, function(t) { lut[tupleid(t)] = 1; });
// generate links for all edges incident on valid tuples
tree.each(function(node) {
var t = node.data,
p = node.parent && node.parent.data;
if (p && lut[tupleid(t)] && lut[tupleid(p)]) {
out.add.push(ingest({source: p, target: t}));
}
});
this.value = out.add;
}
else if (pulse.changed(pulse.MOD)) {
// build lookup table of modified tuples
pulse.visit(pulse.MOD, function(t) { lut[tupleid(t)] = 1; });
// gather links incident on modified tuples
links.forEach(function(link) {
if (lut[tupleid(link.source)] || lut[tupleid(link.target)]) {
out.mod.push(link);
}
});
}
return out;
};