1 | import {Transform, ingest} from 'vega-dataflow';
|
2 | import {inherits, truthy} from 'vega-util';
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | export default function Cross(params) {
|
13 | Transform.call(this, null, params);
|
14 | }
|
15 |
|
16 | Cross.Definition = {
|
17 | 'type': 'Cross',
|
18 | 'metadata': {'generates': true},
|
19 | 'params': [
|
20 | { 'name': 'filter', 'type': 'expr' },
|
21 | { 'name': 'as', 'type': 'string', 'array': true, 'length': 2, 'default': ['a', 'b'] }
|
22 | ]
|
23 | };
|
24 |
|
25 | var prototype = inherits(Cross, Transform);
|
26 |
|
27 | prototype.transform = function(_, pulse) {
|
28 | var out = pulse.fork(pulse.NO_SOURCE),
|
29 | data = this.value,
|
30 | as = _.as || ['a', 'b'],
|
31 | a = as[0], b = as[1],
|
32 | reset = !data
|
33 | || pulse.changed(pulse.ADD_REM)
|
34 | || _.modified('as')
|
35 | || _.modified('filter');
|
36 |
|
37 | if (reset) {
|
38 | if (data) out.rem = data;
|
39 | data = pulse.materialize(pulse.SOURCE).source;
|
40 | out.add = this.value = cross(data, a, b, _.filter || truthy);
|
41 | } else {
|
42 | out.mod = data;
|
43 | }
|
44 |
|
45 | out.source = this.value;
|
46 | return out.modifies(as);
|
47 | };
|
48 |
|
49 | function cross(input, a, b, filter) {
|
50 | var data = [],
|
51 | t = {},
|
52 | n = input.length,
|
53 | i = 0,
|
54 | j, left;
|
55 |
|
56 | for (; i<n; ++i) {
|
57 | t[a] = left = input[i];
|
58 | for (j=0; j<n; ++j) {
|
59 | t[b] = input[j];
|
60 | if (filter(t)) {
|
61 | data.push(ingest(t));
|
62 | t = {};
|
63 | t[a] = left;
|
64 | }
|
65 | }
|
66 | }
|
67 |
|
68 | return data;
|
69 | }
|