Skip to content

Commit dc9f4e5

Browse files
committed
accept objects for encoded typedarrays in data_array valType
- move decoding step to the start of calc data
1 parent dfd122b commit dc9f4e5

File tree

9 files changed

+135
-25
lines changed

9 files changed

+135
-25
lines changed

.eslintrc

+6
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,14 @@
1414
"Float32Array": true,
1515
"Float64Array": true,
1616
"Uint8Array": true,
17+
"Int8Array": true,
18+
"Uint8ClampedArray": true,
1719
"Int16Array": true,
20+
"Uint16Array": true,
1821
"Int32Array": true,
22+
"Uint32Array": true,
23+
"BigInt64Array": true,
24+
"BigUint64Array": true,
1925
"ArrayBuffer": true,
2026
"DataView": true,
2127
"SVGElement": false

package-lock.json

+17-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"@turf/bbox": "^6.0.1",
6464
"@turf/centroid": "^6.0.2",
6565
"alpha-shape": "^1.0.0",
66+
"base64-arraybuffer": "^0.2.0",
6667
"canvas-fit": "^1.5.0",
6768
"color-alpha": "1.0.4",
6869
"color-normalize": "1.5.0",

src/lib/coerce.js

+32-5
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,49 @@ var DESELECTDIM = require('../constants/interactions').DESELECTDIM;
1818
var nestedProperty = require('./nested_property');
1919
var counterRegex = require('./regex').counter;
2020
var modHalf = require('./mod').modHalf;
21+
var isPlainObject = require('./is_plain_object');
2122
var isArrayOrTypedArray = require('./array').isArrayOrTypedArray;
2223

24+
var typedArrays = {
25+
int8: typeof Int8Array !== 'undefined' ? 1 : 0,
26+
uint8: typeof Uint8Array !== 'undefined' ? 1 : 0,
27+
uint8clamped: typeof Uint8ClampedArray !== 'undefined' ? 1 : 0,
28+
int16: typeof Int16Array !== 'undefined' ? 1 : 0,
29+
uint16: typeof Uint16Array !== 'undefined' ? 1 : 0,
30+
int32: typeof Int32Array !== 'undefined' ? 1 : 0,
31+
uint32: typeof Uint32Array !== 'undefined' ? 1 : 0,
32+
float32: typeof Float32Array !== 'undefined' ? 1 : 0,
33+
float64: typeof Float64Array !== 'undefined' ? 1 : 0,
34+
bigint64: typeof BigInt64Array !== 'undefined' ? 1 : 0,
35+
biguint64: typeof BigUint64Array !== 'undefined' ? 1 : 0
36+
};
37+
2338
exports.valObjectMeta = {
2439
data_array: {
2540
// You can use *dflt=[] to force said array to exist though.
2641
description: [
2742
'An {array} of data.',
28-
'The value MUST be an {array}, or we ignore it.',
29-
'Note that typed arrays (e.g. Float32Array) are supported.'
43+
'The value could be an {array}',
44+
'noting that typed arrays (e.g. Float32Array) are also supported.',
45+
'It could also be an object in the form of',
46+
'v: {, dtype: \'float32\', bvals: [/* ... */]}, shape: [dim0 (, dim1, (dim3))]',
47+
'otherwise, it would be ignored.'
3048
].join(' '),
3149
requiredOpts: [],
3250
otherOpts: ['dflt'],
3351
coerceFunction: function(v, propOut, dflt) {
34-
// TODO maybe `v: {type: 'float32', vals: [/* ... */]}` also
35-
if(isArrayOrTypedArray(v)) propOut.set(v);
36-
else if(dflt !== undefined) propOut.set(dflt);
52+
var wasSet;
53+
if(isArrayOrTypedArray(v)) {
54+
propOut.set(v);
55+
wasSet = true;
56+
} else if(isPlainObject(v)) {
57+
var T = typedArrays[v.dtype];
58+
if(T) {
59+
propOut.set(v);
60+
wasSet = true;
61+
}
62+
}
63+
if(!wasSet && dflt !== undefined) propOut.set(dflt);
3764
}
3865
},
3966
enumerated: {

src/plots/plots.js

+44
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
var d3 = require('d3');
1212
var timeFormatLocale = require('d3-time-format').timeFormatLocale;
1313
var isNumeric = require('fast-isnumeric');
14+
var b64 = require('base64-arraybuffer');
1415

1516
var Registry = require('../registry');
1617
var PlotSchema = require('../plot_api/plot_schema');
@@ -2848,7 +2849,50 @@ function _transition(gd, transitionOpts, opts) {
28482849
return transitionStarting.then(function() { return gd; });
28492850
}
28502851

2852+
var typedArrays = {
2853+
int8: typeof Int8Array !== 'undefined' ? Int8Array : null,
2854+
uint8: typeof Uint8Array !== 'undefined' ? Uint8Array : null,
2855+
uint8clamped: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : null,
2856+
int16: typeof Int16Array !== 'undefined' ? Int16Array : null,
2857+
uint16: typeof Uint16Array !== 'undefined' ? Uint16Array : null,
2858+
int32: typeof Int32Array !== 'undefined' ? Int32Array : null,
2859+
uint32: typeof Uint32Array !== 'undefined' ? Uint32Array : null,
2860+
float32: typeof Float32Array !== 'undefined' ? Float32Array : null,
2861+
float64: typeof Float64Array !== 'undefined' ? Float64Array : null,
2862+
bigint64: typeof BigInt64Array !== 'undefined' ? BigInt64Array : null,
2863+
biguint64: typeof BigUint64Array !== 'undefined' ? BigUint64Array : null
2864+
};
2865+
2866+
function _decode(cont) {
2867+
if(cont.dtype && cont.bvals) {
2868+
var T = typedArrays[cont.dtype];
2869+
if(T) {
2870+
return new T(b64.decode(cont.bvals));
2871+
}
2872+
}
2873+
2874+
for(var prop in cont) {
2875+
if(prop[0] !== '_' && cont.hasOwnProperty(prop)) {
2876+
var item = cont[prop];
2877+
if(Lib.isPlainObject(item)) {
2878+
var r = _decode(item);
2879+
if(r !== undefined) cont[prop] = r;
2880+
}
2881+
}
2882+
}
2883+
}
2884+
2885+
function decodeB64Arrays(gd) {
2886+
for(var i = 0; i < gd._fullData.length; i++) {
2887+
_decode(gd._fullData[i]);
2888+
}
2889+
2890+
_decode(gd._fullLayout);
2891+
}
2892+
28512893
plots.doCalcdata = function(gd, traces) {
2894+
decodeB64Arrays(gd);
2895+
28522896
var axList = axisIDs.list(gd);
28532897
var fullData = gd._fullData;
28542898
var fullLayout = gd._fullLayout;

src/traces/heatmap/xyz_defaults.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,25 @@ module.exports = function handleXYZDefaults(traceIn, traceOut, coerce, layout, x
1919
yName = yName || 'y';
2020
var x, y;
2121

22-
if(z === undefined || !z.length) return 0;
22+
var shapeX = x ? (x.shape ? x.shape[0] : x.length) || 0 : 0;
23+
var shapeY = y ? (y.shape ? y.shape[0] : y.length) || 0 : 0;
24+
var shapeZ = z ? (z.shape ? z.shape[0] : z.length) || 0 : 0;
2325

24-
if(Lib.isArray1D(traceIn.z)) {
26+
var zlen = shapeZ || (z && z.length) || 0;
27+
28+
if(z === undefined || !zlen) return 0;
29+
30+
if(Lib.isArray1D(traceIn.z) || (z && z.shape && z.shape.length === 1)) {
2531
x = coerce(xName);
2632
y = coerce(yName);
2733

28-
var xlen = Lib.minRowLength(x);
29-
var ylen = Lib.minRowLength(y);
34+
var xlen = shapeX || Lib.minRowLength(x);
35+
var ylen = shapeY || Lib.minRowLength(y);
3036

3137
// column z must be accompanied by xName and yName arrays
3238
if(xlen === 0 || ylen === 0) return 0;
3339

34-
traceOut._length = Math.min(xlen, ylen, z.length);
40+
traceOut._length = Math.min(xlen, ylen, zlen);
3541
} else {
3642
x = coordDefaults(xName, coerce);
3743
y = coordDefaults(yName, coerce);

src/traces/isosurface/defaults.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,18 @@ function supplyIsoDefaults(traceIn, traceOut, defaultColor, layout, coerce) {
3838
var z = coerce('z');
3939
var value = coerce('value');
4040

41-
if(
42-
!x || !x.length ||
43-
!y || !y.length ||
44-
!z || !z.length ||
45-
!value || !value.length
46-
) {
41+
var len = 0;
42+
43+
if(x && y && z && value) {
44+
len = Math.min(
45+
(x.shape ? x.shape[0] : x.length) || 0,
46+
(y.shape ? y.shape[0] : y.length) || 0,
47+
(z.shape ? z.shape[0] : z.length) || 0,
48+
(value.shape ? value.shape[0] : value.length) || 0
49+
);
50+
}
51+
52+
if(!len) {
4753
traceOut.visible = false;
4854
return;
4955
}

src/traces/scatter/xy_defaults.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,22 @@ module.exports = function handleXYDefaults(traceIn, traceOut, layout, coerce) {
1919
var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');
2020
handleCalendarDefaults(traceIn, traceOut, ['x', 'y'], layout);
2121

22+
var shapeX = x && x.shape ? x.shape[0] : 0;
23+
var shapeY = y && y.shape ? y.shape[0] : 0;
24+
2225
if(x) {
23-
var xlen = Lib.minRowLength(x);
26+
var xlen = shapeX || Lib.minRowLength(x);
2427
if(y) {
25-
len = Math.min(xlen, Lib.minRowLength(y));
28+
len = shapeY || Math.min(xlen, Lib.minRowLength(y));
2629
} else {
27-
len = xlen;
30+
len = shapeX || xlen;
2831
coerce('y0');
2932
coerce('dy');
3033
}
3134
} else {
3235
if(!y) return 0;
3336

34-
len = Lib.minRowLength(y);
37+
len = shapeY || Lib.minRowLength(y);
3538
coerce('x0');
3639
coerce('dx');
3740
}

src/traces/scatter3d/defaults.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,12 @@ function handleXYZDefaults(traceIn, traceOut, coerce, layout) {
7878
handleCalendarDefaults(traceIn, traceOut, ['x', 'y', 'z'], layout);
7979

8080
if(x && y && z) {
81+
var shapeX = (x.shape ? x.shape[0] : x.length) || 0;
82+
var shapeY = (y.shape ? y.shape[0] : y.length) || 0;
83+
var shapeZ = (z.shape ? z.shape[0] : z.length) || 0;
84+
8185
// TODO: what happens if one is missing?
82-
len = Math.min(x.length, y.length, z.length);
86+
len = Math.min(shapeX, shapeY, shapeZ);
8387
traceOut._length = traceOut._xlength = traceOut._ylength = traceOut._zlength = len;
8488
}
8589

0 commit comments

Comments
 (0)