UNPKG

2.56 kBJavaScriptView Raw
1import {Transform} from 'vega-dataflow';
2import {accessorName, error, inherits} from 'vega-util';
3
4/**
5 * Extend tuples by joining them with values from a lookup table.
6 * @constructor
7 * @param {object} params - The parameters for this operator.
8 * @param {Map} params.index - The lookup table map.
9 * @param {Array<function(object): *} params.fields - The fields to lookup.
10 * @param {Array<string>} params.as - Output field names for each lookup value.
11 * @param {*} [params.default] - A default value to use if lookup fails.
12 */
13export default function Lookup(params) {
14 Transform.call(this, {}, params);
15}
16
17Lookup.Definition = {
18 'type': 'Lookup',
19 'metadata': {'modifies': true},
20 'params': [
21 { 'name': 'index', 'type': 'index', 'params': [
22 {'name': 'from', 'type': 'data', 'required': true },
23 {'name': 'key', 'type': 'field', 'required': true }
24 ] },
25 { 'name': 'values', 'type': 'field', 'array': true },
26 { 'name': 'fields', 'type': 'field', 'array': true, 'required': true },
27 { 'name': 'as', 'type': 'string', 'array': true },
28 { 'name': 'default', 'default': null }
29 ]
30};
31
32inherits(Lookup, Transform, {
33 transform(_, pulse) {
34 const keys = _.fields,
35 index = _.index,
36 values = _.values,
37 defaultValue = _.default==null ? null : _.default,
38 reset = _.modified(),
39 n = keys.length;
40
41 let flag = reset ? pulse.SOURCE : pulse.ADD,
42 out = pulse,
43 as = _.as,
44 set, m, mods;
45
46 if (values) {
47 m = values.length;
48
49 if (n > 1 && !as) {
50 error('Multi-field lookup requires explicit "as" parameter.');
51 }
52 if (as && as.length !== n * m) {
53 error('The "as" parameter has too few output field names.');
54 }
55 as = as || values.map(accessorName);
56
57 set = function(t) {
58 for (var i=0, k=0, j, v; i<n; ++i) {
59 v = index.get(keys[i](t));
60 if (v == null) for (j=0; j<m; ++j, ++k) t[as[k]] = defaultValue;
61 else for (j=0; j<m; ++j, ++k) t[as[k]] = values[j](v);
62 }
63 };
64 } else {
65 if (!as) {
66 error('Missing output field names.');
67 }
68
69 set = function(t) {
70 for (var i=0, v; i<n; ++i) {
71 v = index.get(keys[i](t));
72 t[as[i]] = v==null ? defaultValue : v;
73 }
74 };
75 }
76
77 if (reset) {
78 out = pulse.reflow(true);
79 } else {
80 mods = keys.some(k =>pulse.modified(k.fields));
81 flag |= (mods ? pulse.MOD : 0);
82 }
83 pulse.visit(flag, set);
84
85 return out.modifies(as);
86 }
87});