1 | import {Transform} from 'vega-dataflow';
|
2 | import {accessorName, error, inherits} from 'vega-util';
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | export default function Lookup(params) {
|
14 | Transform.call(this, {}, params);
|
15 | }
|
16 |
|
17 | Lookup.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 |
|
32 | inherits(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 | });
|