-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
Treeify.js
94 lines (82 loc) · 2.52 KB
/
Treeify.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
var dl = require('datalib'),
Tuple = require('vega-dataflow').Tuple,
log = require('vega-logging'),
Transform = require('./Transform'),
BatchTransform = require('./BatchTransform');
function Treeify(graph) {
BatchTransform.prototype.init.call(this, graph);
Transform.addParameters(this, {
groupby: {type: 'array<field>'}
});
this._output = {
'children': 'children',
'parent': 'parent'
};
return this.router(true).produces(true);
}
var prototype = (Treeify.prototype = Object.create(BatchTransform.prototype));
prototype.constructor = Treeify;
prototype.batchTransform = function(input, data) {
log.debug(input, ['treeifying']);
var fields = this.param('groupby').field,
childField = this._output.children,
parentField = this._output.parent,
summary = [{name:'*', ops: ['values'], as: [childField]}],
aggrs = fields.map(function(f) {
return dl.groupby(f).summarize(summary);
}),
prev = this._internal || [], curr = [], i, n;
function level(index, node, values) {
var vals = aggrs[index].execute(values);
node[childField] = vals;
vals.forEach(function(n) {
n[parentField] = node;
curr.push(Tuple.ingest(n));
if (index+1 < fields.length) level(index+1, n, n[childField]);
else n[childField].forEach(function(c) { c[parentField] = n; });
});
}
var root = Tuple.ingest({});
root[parentField] = null;
curr.push(root);
level(0, root, data);
// update changeset with internal nodes
for (i=0, n=curr.length; i<n; ++i) {
input.add.push(curr[i]);
}
for (i=0, n=prev.length; i<n; ++i) {
input.rem.push(prev[i]);
}
this._internal = curr;
return input;
};
module.exports = Treeify;
Treeify.schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Treeify transform",
"type": "object",
"properties": {
"type": {"enum": ["treeify"]},
"groupby": {
"description": "An ordered list of fields by which to group tuples into a tree.",
"oneOf": [
{
"type": "array",
"items": {"oneOf": [{"type": "string"}, {"$ref": "#/refs/signal"}]}
},
{"$ref": "#/refs/signal"}
]
},
"output": {
"type": "object",
"description": "Rename the output data fields",
"properties": {
"children": {"type": "string", "default": "children"},
"parent": {"type": "string", "default": "parent"}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"required": ["type", "groupby"]
};