vega 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +25 -3
- data/lib/vega/version.rb +1 -1
- data/licenses/LICENSE-vega-interpreter.txt +27 -0
- data/vendor/assets/javascripts/vega-interpreter.js +311 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3b596c09118b82dc1166f6413ff31aae7801b79db73f4dc2e09acab9ccfa21a
|
4
|
+
data.tar.gz: 9ce59baf66bfd278f457a7686d8d8b2e4aa9c6f046d99b1d1184d206b6a680a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79c6c4705a054f0f9b9a4001f10496c1af17440ebf672c77ca856a35c9778c98ed40ce5f31ac90f31b05ec23df9640ff41d070b31b8466e8dec7930b1cf1a56d
|
7
|
+
data.tar.gz: ff0808b2c0cbaac73e266798cb048c6d0884e36b135f76bc5ebe74af5125a42a7e9a7018c22a7077a4c8530be431171cdc3b6d4a9e28a48643a24772b65537f7
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -56,9 +56,9 @@ No additional set up is needed.
|
|
56
56
|
For Sinatra and other web frameworks, include the Vega JavaScript files on pages with charts:
|
57
57
|
|
58
58
|
```html
|
59
|
-
<script src="https://cdn.jsdelivr.net/npm/vega@5.
|
60
|
-
<script src="https://cdn.jsdelivr.net/npm/vega-lite@4.
|
61
|
-
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6.
|
59
|
+
<script src="https://cdn.jsdelivr.net/npm/vega@5.19.1"></script>
|
60
|
+
<script src="https://cdn.jsdelivr.net/npm/vega-lite@4.17.0"></script>
|
61
|
+
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6.15.1"></script>
|
62
62
|
```
|
63
63
|
|
64
64
|
## Getting Started
|
@@ -318,6 +318,28 @@ Get the spec for a chart
|
|
318
318
|
chart.spec
|
319
319
|
```
|
320
320
|
|
321
|
+
## Content Security Policy (CSP)
|
322
|
+
|
323
|
+
By default, the Vega parser uses the Function constructor, which [can cause issues with CSP](https://vega.github.io/vega/usage/interpreter/).
|
324
|
+
|
325
|
+
For Rails 6 / Webpacker, run:
|
326
|
+
|
327
|
+
```sh
|
328
|
+
yarn add vega-interpreter
|
329
|
+
```
|
330
|
+
|
331
|
+
For Rails 5 / Sprockets, add to `app/assets/javascripts/application.js`:
|
332
|
+
|
333
|
+
```js
|
334
|
+
//= require vega-interpreter
|
335
|
+
```
|
336
|
+
|
337
|
+
And set embed options for your charts
|
338
|
+
|
339
|
+
```ruby
|
340
|
+
embed_options(ast: true)
|
341
|
+
```
|
342
|
+
|
321
343
|
## History
|
322
344
|
|
323
345
|
View the [changelog](https://github.com/ankane/vega/blob/master/CHANGELOG.md)
|
data/lib/vega/version.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
Copyright (c) 2015-2018, University of Washington Interactive Data Lab
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
12
|
+
and/or other materials provided with the distribution.
|
13
|
+
|
14
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
15
|
+
may be used to endorse or promote products derived from this software
|
16
|
+
without specific prior written permission.
|
17
|
+
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
22
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,311 @@
|
|
1
|
+
(function (global, factory) {
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vega = global.vega || {}));
|
5
|
+
}(this, (function (exports) { 'use strict';
|
6
|
+
|
7
|
+
function adjustSpatial (item, encode, swap) {
|
8
|
+
let t;
|
9
|
+
|
10
|
+
if (encode.x2) {
|
11
|
+
if (encode.x) {
|
12
|
+
if (swap && item.x > item.x2) {
|
13
|
+
t = item.x;
|
14
|
+
item.x = item.x2;
|
15
|
+
item.x2 = t;
|
16
|
+
}
|
17
|
+
|
18
|
+
item.width = item.x2 - item.x;
|
19
|
+
} else {
|
20
|
+
item.x = item.x2 - (item.width || 0);
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
if (encode.xc) {
|
25
|
+
item.x = item.xc - (item.width || 0) / 2;
|
26
|
+
}
|
27
|
+
|
28
|
+
if (encode.y2) {
|
29
|
+
if (encode.y) {
|
30
|
+
if (swap && item.y > item.y2) {
|
31
|
+
t = item.y;
|
32
|
+
item.y = item.y2;
|
33
|
+
item.y2 = t;
|
34
|
+
}
|
35
|
+
|
36
|
+
item.height = item.y2 - item.y;
|
37
|
+
} else {
|
38
|
+
item.y = item.y2 - (item.height || 0);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
if (encode.yc) {
|
43
|
+
item.y = item.yc - (item.height || 0) / 2;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
var Constants = {
|
48
|
+
NaN: NaN,
|
49
|
+
E: Math.E,
|
50
|
+
LN2: Math.LN2,
|
51
|
+
LN10: Math.LN10,
|
52
|
+
LOG2E: Math.LOG2E,
|
53
|
+
LOG10E: Math.LOG10E,
|
54
|
+
PI: Math.PI,
|
55
|
+
SQRT1_2: Math.SQRT1_2,
|
56
|
+
SQRT2: Math.SQRT2,
|
57
|
+
MIN_VALUE: Number.MIN_VALUE,
|
58
|
+
MAX_VALUE: Number.MAX_VALUE
|
59
|
+
};
|
60
|
+
|
61
|
+
var Ops = {
|
62
|
+
'*': (a, b) => a * b,
|
63
|
+
'+': (a, b) => a + b,
|
64
|
+
'-': (a, b) => a - b,
|
65
|
+
'/': (a, b) => a / b,
|
66
|
+
'%': (a, b) => a % b,
|
67
|
+
'>': (a, b) => a > b,
|
68
|
+
'<': (a, b) => a < b,
|
69
|
+
'<=': (a, b) => a <= b,
|
70
|
+
'>=': (a, b) => a >= b,
|
71
|
+
'==': (a, b) => a == b,
|
72
|
+
'!=': (a, b) => a != b,
|
73
|
+
'===': (a, b) => a === b,
|
74
|
+
'!==': (a, b) => a !== b,
|
75
|
+
'&': (a, b) => a & b,
|
76
|
+
'|': (a, b) => a | b,
|
77
|
+
'^': (a, b) => a ^ b,
|
78
|
+
'<<': (a, b) => a << b,
|
79
|
+
'>>': (a, b) => a >> b,
|
80
|
+
'>>>': (a, b) => a >>> b
|
81
|
+
};
|
82
|
+
|
83
|
+
var Unary = {
|
84
|
+
'+': a => +a,
|
85
|
+
'-': a => -a,
|
86
|
+
'~': a => ~a,
|
87
|
+
'!': a => !a
|
88
|
+
};
|
89
|
+
|
90
|
+
const slice = Array.prototype.slice;
|
91
|
+
|
92
|
+
const apply = (m, args, cast) => {
|
93
|
+
const obj = cast ? cast(args[0]) : args[0];
|
94
|
+
return obj[m].apply(obj, slice.call(args, 1));
|
95
|
+
};
|
96
|
+
|
97
|
+
const datetime = (y, m, d, H, M, S, ms) => new Date(y, m || 0, d != null ? d : 1, H || 0, M || 0, S || 0, ms || 0);
|
98
|
+
|
99
|
+
var Functions = {
|
100
|
+
// math functions
|
101
|
+
isNaN: Number.isNaN,
|
102
|
+
isFinite: Number.isFinite,
|
103
|
+
abs: Math.abs,
|
104
|
+
acos: Math.acos,
|
105
|
+
asin: Math.asin,
|
106
|
+
atan: Math.atan,
|
107
|
+
atan2: Math.atan2,
|
108
|
+
ceil: Math.ceil,
|
109
|
+
cos: Math.cos,
|
110
|
+
exp: Math.exp,
|
111
|
+
floor: Math.floor,
|
112
|
+
log: Math.log,
|
113
|
+
max: Math.max,
|
114
|
+
min: Math.min,
|
115
|
+
pow: Math.pow,
|
116
|
+
random: Math.random,
|
117
|
+
round: Math.round,
|
118
|
+
sin: Math.sin,
|
119
|
+
sqrt: Math.sqrt,
|
120
|
+
tan: Math.tan,
|
121
|
+
clamp: (a, b, c) => Math.max(b, Math.min(c, a)),
|
122
|
+
// date functions
|
123
|
+
now: Date.now,
|
124
|
+
utc: Date.UTC,
|
125
|
+
datetime: datetime,
|
126
|
+
date: d => new Date(d).getDate(),
|
127
|
+
day: d => new Date(d).getDay(),
|
128
|
+
year: d => new Date(d).getFullYear(),
|
129
|
+
month: d => new Date(d).getMonth(),
|
130
|
+
hours: d => new Date(d).getHours(),
|
131
|
+
minutes: d => new Date(d).getMinutes(),
|
132
|
+
seconds: d => new Date(d).getSeconds(),
|
133
|
+
milliseconds: d => new Date(d).getMilliseconds(),
|
134
|
+
time: d => new Date(d).getTime(),
|
135
|
+
timezoneoffset: d => new Date(d).getTimezoneOffset(),
|
136
|
+
utcdate: d => new Date(d).getUTCDate(),
|
137
|
+
utcday: d => new Date(d).getUTCDay(),
|
138
|
+
utcyear: d => new Date(d).getUTCFullYear(),
|
139
|
+
utcmonth: d => new Date(d).getUTCMonth(),
|
140
|
+
utchours: d => new Date(d).getUTCHours(),
|
141
|
+
utcminutes: d => new Date(d).getUTCMinutes(),
|
142
|
+
utcseconds: d => new Date(d).getUTCSeconds(),
|
143
|
+
utcmilliseconds: d => new Date(d).getUTCMilliseconds(),
|
144
|
+
// sequence functions
|
145
|
+
length: x => x.length,
|
146
|
+
join: function () {
|
147
|
+
return apply('join', arguments);
|
148
|
+
},
|
149
|
+
indexof: function () {
|
150
|
+
return apply('indexOf', arguments);
|
151
|
+
},
|
152
|
+
lastindexof: function () {
|
153
|
+
return apply('lastIndexOf', arguments);
|
154
|
+
},
|
155
|
+
slice: function () {
|
156
|
+
return apply('slice', arguments);
|
157
|
+
},
|
158
|
+
reverse: x => x.slice().reverse(),
|
159
|
+
// string functions
|
160
|
+
parseFloat: parseFloat,
|
161
|
+
parseInt: parseInt,
|
162
|
+
upper: x => String(x).toUpperCase(),
|
163
|
+
lower: x => String(x).toLowerCase(),
|
164
|
+
substring: function () {
|
165
|
+
return apply('substring', arguments, String);
|
166
|
+
},
|
167
|
+
split: function () {
|
168
|
+
return apply('split', arguments, String);
|
169
|
+
},
|
170
|
+
replace: function () {
|
171
|
+
return apply('replace', arguments, String);
|
172
|
+
},
|
173
|
+
trim: x => String(x).trim(),
|
174
|
+
// regexp functions
|
175
|
+
regexp: RegExp,
|
176
|
+
test: (r, t) => RegExp(r).test(t)
|
177
|
+
};
|
178
|
+
|
179
|
+
const EventFunctions = ['view', 'item', 'group', 'xy', 'x', 'y'];
|
180
|
+
const Visitors = {
|
181
|
+
Literal: ($, n) => n.value,
|
182
|
+
Identifier: ($, n) => {
|
183
|
+
const id = n.name;
|
184
|
+
return $.memberDepth > 0 ? id : id === 'datum' ? $.datum : id === 'event' ? $.event : id === 'item' ? $.item : Constants[id] || $.params['$' + id];
|
185
|
+
},
|
186
|
+
MemberExpression: ($, n) => {
|
187
|
+
const d = !n.computed,
|
188
|
+
o = $(n.object);
|
189
|
+
if (d) $.memberDepth += 1;
|
190
|
+
const p = $(n.property);
|
191
|
+
if (d) $.memberDepth -= 1;
|
192
|
+
return o[p];
|
193
|
+
},
|
194
|
+
CallExpression: ($, n) => {
|
195
|
+
const args = n.arguments;
|
196
|
+
let name = n.callee.name; // handle special internal functions used by encoders
|
197
|
+
// re-route to corresponding standard function
|
198
|
+
|
199
|
+
if (name.startsWith('_')) {
|
200
|
+
name = name.slice(1);
|
201
|
+
} // special case "if" due to conditional evaluation of branches
|
202
|
+
|
203
|
+
|
204
|
+
return name === 'if' ? $(args[0]) ? $(args[1]) : $(args[2]) : ($.fn[name] || Functions[name]).apply($.fn, args.map($));
|
205
|
+
},
|
206
|
+
ArrayExpression: ($, n) => n.elements.map($),
|
207
|
+
BinaryExpression: ($, n) => Ops[n.operator]($(n.left), $(n.right)),
|
208
|
+
UnaryExpression: ($, n) => Unary[n.operator]($(n.argument)),
|
209
|
+
ConditionalExpression: ($, n) => $(n.test) ? $(n.consequent) : $(n.alternate),
|
210
|
+
LogicalExpression: ($, n) => n.operator === '&&' ? $(n.left) && $(n.right) : $(n.left) || $(n.right),
|
211
|
+
ObjectExpression: ($, n) => n.properties.reduce((o, p) => {
|
212
|
+
$.memberDepth += 1;
|
213
|
+
const k = $(p.key);
|
214
|
+
$.memberDepth -= 1;
|
215
|
+
o[k] = $(p.value);
|
216
|
+
return o;
|
217
|
+
}, {})
|
218
|
+
};
|
219
|
+
function interpret (ast, fn, params, datum, event, item) {
|
220
|
+
const $ = n => Visitors[n.type]($, n);
|
221
|
+
|
222
|
+
$.memberDepth = 0;
|
223
|
+
$.fn = Object.create(fn);
|
224
|
+
$.params = params;
|
225
|
+
$.datum = datum;
|
226
|
+
$.event = event;
|
227
|
+
$.item = item; // route event functions to annotated vega event context
|
228
|
+
|
229
|
+
EventFunctions.forEach(f => $.fn[f] = (...args) => event.vega[f](...args));
|
230
|
+
return $(ast);
|
231
|
+
}
|
232
|
+
|
233
|
+
var expression = {
|
234
|
+
/**
|
235
|
+
* Parse an expression used to update an operator value.
|
236
|
+
*/
|
237
|
+
operator(ctx, expr) {
|
238
|
+
const ast = expr.ast,
|
239
|
+
fn = ctx.functions;
|
240
|
+
return _ => interpret(ast, fn, _);
|
241
|
+
},
|
242
|
+
|
243
|
+
/**
|
244
|
+
* Parse an expression provided as an operator parameter value.
|
245
|
+
*/
|
246
|
+
parameter(ctx, expr) {
|
247
|
+
const ast = expr.ast,
|
248
|
+
fn = ctx.functions;
|
249
|
+
return (datum, _) => interpret(ast, fn, _, datum);
|
250
|
+
},
|
251
|
+
|
252
|
+
/**
|
253
|
+
* Parse an expression applied to an event stream.
|
254
|
+
*/
|
255
|
+
event(ctx, expr) {
|
256
|
+
const ast = expr.ast,
|
257
|
+
fn = ctx.functions;
|
258
|
+
return event => interpret(ast, fn, undefined, undefined, event);
|
259
|
+
},
|
260
|
+
|
261
|
+
/**
|
262
|
+
* Parse an expression used to handle an event-driven operator update.
|
263
|
+
*/
|
264
|
+
handler(ctx, expr) {
|
265
|
+
const ast = expr.ast,
|
266
|
+
fn = ctx.functions;
|
267
|
+
return (_, event) => {
|
268
|
+
const datum = event.item && event.item.datum;
|
269
|
+
return interpret(ast, fn, _, datum, event);
|
270
|
+
};
|
271
|
+
},
|
272
|
+
|
273
|
+
/**
|
274
|
+
* Parse an expression that performs visual encoding.
|
275
|
+
*/
|
276
|
+
encode(ctx, encode) {
|
277
|
+
const {
|
278
|
+
marktype,
|
279
|
+
channels
|
280
|
+
} = encode,
|
281
|
+
fn = ctx.functions,
|
282
|
+
swap = marktype === 'group' || marktype === 'image' || marktype === 'rect';
|
283
|
+
return (item, _) => {
|
284
|
+
const datum = item.datum;
|
285
|
+
let m = 0,
|
286
|
+
v;
|
287
|
+
|
288
|
+
for (const name in channels) {
|
289
|
+
v = interpret(channels[name].ast, fn, _, datum, undefined, item);
|
290
|
+
|
291
|
+
if (item[name] !== v) {
|
292
|
+
item[name] = v;
|
293
|
+
m = 1;
|
294
|
+
}
|
295
|
+
}
|
296
|
+
|
297
|
+
if (marktype !== 'rule') {
|
298
|
+
adjustSpatial(item, channels, swap);
|
299
|
+
}
|
300
|
+
|
301
|
+
return m;
|
302
|
+
};
|
303
|
+
}
|
304
|
+
|
305
|
+
};
|
306
|
+
|
307
|
+
exports.expressionInterpreter = expression;
|
308
|
+
|
309
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
310
|
+
|
311
|
+
})));
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vega
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: andrew@ankane.org
|
@@ -28,9 +28,11 @@ files:
|
|
28
28
|
- lib/vega/spec.rb
|
29
29
|
- lib/vega/version.rb
|
30
30
|
- licenses/LICENSE-vega-embed.txt
|
31
|
+
- licenses/LICENSE-vega-interpreter.txt
|
31
32
|
- licenses/LICENSE-vega-lite.txt
|
32
33
|
- licenses/LICENSE-vega.txt
|
33
34
|
- vendor/assets/javascripts/vega-embed.js
|
35
|
+
- vendor/assets/javascripts/vega-interpreter.js
|
34
36
|
- vendor/assets/javascripts/vega-lite.js
|
35
37
|
- vendor/assets/javascripts/vega.js
|
36
38
|
homepage: https://github.com/ankane/vega
|