Skip to content

Commit c1c54e8

Browse files
committed
handle buffer for arrayOk attributes
- handle line color when marker color is defined by a buffer
1 parent 78438fa commit c1c54e8

File tree

16 files changed

+144
-51
lines changed

16 files changed

+144
-51
lines changed

src/components/colorscale/helpers.js

+2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ function hasColorscale(trace, containerStr, colorKey) {
1313
var container = containerStr ?
1414
Lib.nestedProperty(trace, containerStr).get() || {} :
1515
trace;
16+
1617
var color = container[colorKey || 'color'];
18+
if(color && color._inputArray) color = color._inputArray;
1719

1820
var isArrayWithOneNumber = false;
1921
if(Lib.isArrayOrTypedArray(color)) {

src/lib/array.js

+2
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ exports.decodeTypedArraySpec = function(vIn) {
154154
out.dtype = v.dtype;
155155
out.shape = shape.join(',');
156156

157+
vIn._inputArray = out;
158+
157159
return out;
158160
};
159161

src/lib/coerce.js

+18-9
Original file line numberDiff line numberDiff line change
@@ -385,15 +385,24 @@ exports.coerce = function(containerIn, containerOut, attributes, attribute, dflt
385385

386386
if(dflt === undefined) dflt = opts.dflt;
387387

388-
/**
389-
* arrayOk: value MAY be an array, then we do no value checking
390-
* at this point, because it can be more complicated than the
391-
* individual form (eg. some array vals can be numbers, even if the
392-
* single values must be color strings)
393-
*/
394-
if(opts.arrayOk && isArrayOrTypedArray(v)) {
395-
propOut.set(v);
396-
return v;
388+
if(opts.arrayOk) {
389+
if(isArrayOrTypedArray(v)) {
390+
/**
391+
* arrayOk: value MAY be an array, then we do no value checking
392+
* at this point, because it can be more complicated than the
393+
* individual form (eg. some array vals can be numbers, even if the
394+
* single values must be color strings)
395+
*/
396+
397+
propOut.set(v);
398+
return v;
399+
} else {
400+
if(isTypedArraySpec(v)) {
401+
v = decodeTypedArraySpec(v);
402+
propOut.set(v);
403+
return v;
404+
}
405+
}
397406
}
398407

399408
var coerceFunction = exports.valObjectMeta[opts.valType].coerceFunction;

src/lib/gl_format_color.js

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ function validateOpacity(opacityIn) {
3131

3232
function formatColor(containerIn, opacityIn, len) {
3333
var colorIn = containerIn.color;
34+
if(colorIn && colorIn._inputArray) colorIn = colorIn._inputArray;
35+
3436
var isArrayColorIn = isArrayOrTypedArray(colorIn);
3537
var isArrayOpacityIn = isArrayOrTypedArray(opacityIn);
3638
var cOpts = Colorscale.extractOpts(containerIn);

src/traces/scatter/defaults.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,17 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
4444
coerce('hovertext');
4545
coerce('mode', defaultMode);
4646

47+
if(subTypes.hasMarkers(traceOut)) {
48+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
49+
}
50+
4751
if(subTypes.hasLines(traceOut)) {
4852
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {backoff: true});
4953
handleLineShapeDefaults(traceIn, traceOut, coerce);
5054
coerce('connectgaps');
5155
coerce('line.simplify');
5256
}
5357

54-
if(subTypes.hasMarkers(traceOut)) {
55-
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
56-
}
57-
5858
if(subTypes.hasText(traceOut)) {
5959
coerce('texttemplate');
6060
handleTextDefaults(traceIn, traceOut, layout, coerce);

src/traces/scatter/line_defaults.js

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = function lineDefaults(traceIn, traceOut, defaultColor, layout,
88
if(!opts) opts = {};
99

1010
var markerColor = (traceIn.marker || {}).color;
11+
if(markerColor && markerColor._inputArray) markerColor = markerColor._inputArray;
1112

1213
coerce('line.color', defaultColor);
1314

src/traces/scatter3d/defaults.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3030

3131
coerce('mode');
3232

33+
if(subTypes.hasMarkers(traceOut)) {
34+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noSelect: true, noAngle: true});
35+
}
36+
3337
if(subTypes.hasLines(traceOut)) {
3438
coerce('connectgaps');
3539
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
3640
}
3741

38-
if(subTypes.hasMarkers(traceOut)) {
39-
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noSelect: true, noAngle: true});
40-
}
41-
4242
if(subTypes.hasText(traceOut)) {
4343
coerce('texttemplate');
4444
handleTextDefaults(traceIn, traceOut, layout, coerce, {noSelect: true});

src/traces/scattercarpet/defaults.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
4141
var defaultMode = len < constants.PTS_LINESONLY ? 'lines+markers' : 'lines';
4242
coerce('mode', defaultMode);
4343

44+
if(subTypes.hasMarkers(traceOut)) {
45+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
46+
}
47+
4448
if(subTypes.hasLines(traceOut)) {
4549
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {backoff: true});
4650
handleLineShapeDefaults(traceIn, traceOut, coerce);
4751
coerce('connectgaps');
4852
}
4953

50-
if(subTypes.hasMarkers(traceOut)) {
51-
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
52-
}
53-
5454
if(subTypes.hasText(traceOut)) {
5555
handleTextDefaults(traceIn, traceOut, layout, coerce);
5656
}

src/traces/scattergeo/defaults.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
5050
coerce('hovertemplate');
5151
coerce('mode');
5252

53+
if(subTypes.hasMarkers(traceOut)) {
54+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
55+
}
56+
5357
if(subTypes.hasLines(traceOut)) {
5458
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
5559
coerce('connectgaps');
5660
}
5761

58-
if(subTypes.hasMarkers(traceOut)) {
59-
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
60-
}
61-
6262
if(subTypes.hasText(traceOut)) {
6363
coerce('texttemplate');
6464
handleTextDefaults(traceIn, traceOut, layout, coerce);

src/traces/scattergl/defaults.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3939
coerce('hovertemplate');
4040
coerce('mode', defaultMode);
4141

42+
if(subTypes.hasMarkers(traceOut)) {
43+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noAngleRef: true, noStandOff: true});
44+
coerce('marker.line.width', isOpen || isBubble ? 1 : 0);
45+
}
46+
4247
if(subTypes.hasLines(traceOut)) {
4348
coerce('connectgaps');
4449
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
4550
coerce('line.shape');
4651
}
4752

48-
if(subTypes.hasMarkers(traceOut)) {
49-
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noAngleRef: true, noStandOff: true});
50-
coerce('marker.line.width', isOpen || isBubble ? 1 : 0);
51-
}
52-
5353
if(subTypes.hasText(traceOut)) {
5454
coerce('texttemplate');
5555
handleTextDefaults(traceIn, traceOut, layout, coerce);

src/traces/scattermapbox/defaults.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3131
coerce('mode');
3232
coerce('below');
3333

34-
if(subTypes.hasLines(traceOut)) {
35-
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noDash: true});
36-
coerce('connectgaps');
37-
}
38-
3934
if(subTypes.hasMarkers(traceOut)) {
4035
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noLine: true, noAngle: true});
4136

@@ -50,6 +45,11 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
5045
}
5146
}
5247

48+
if(subTypes.hasLines(traceOut)) {
49+
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noDash: true});
50+
coerce('connectgaps');
51+
}
52+
5353
var clusterMaxzoom = coerce2('cluster.maxzoom');
5454
var clusterStep = coerce2('cluster.step');
5555
var clusterColor = coerce2('cluster.color', (traceOut.marker && traceOut.marker.color) || defaultColor);

src/traces/scatterpolar/defaults.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
2929
coerce('hovertext');
3030
if(traceOut.hoveron !== 'fills') coerce('hovertemplate');
3131

32+
if(subTypes.hasMarkers(traceOut)) {
33+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
34+
}
35+
3236
if(subTypes.hasLines(traceOut)) {
3337
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {backoff: true});
3438
handleLineShapeDefaults(traceIn, traceOut, coerce);
3539
coerce('connectgaps');
3640
}
3741

38-
if(subTypes.hasMarkers(traceOut)) {
39-
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
40-
}
41-
4242
if(subTypes.hasText(traceOut)) {
4343
coerce('texttemplate');
4444
handleTextDefaults(traceIn, traceOut, layout, coerce);

src/traces/scatterpolargl/defaults.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
2929
coerce('hovertext');
3030
if(traceOut.hoveron !== 'fills') coerce('hovertemplate');
3131

32+
if(subTypes.hasMarkers(traceOut)) {
33+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noAngleRef: true, noStandOff: true});
34+
}
35+
3236
if(subTypes.hasLines(traceOut)) {
3337
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
3438
coerce('connectgaps');
3539
}
3640

37-
if(subTypes.hasMarkers(traceOut)) {
38-
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noAngleRef: true, noStandOff: true});
39-
}
40-
4141
if(subTypes.hasText(traceOut)) {
4242
coerce('texttemplate');
4343
handleTextDefaults(traceIn, traceOut, layout, coerce);

src/traces/scattersmith/defaults.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
2828
coerce('hovertext');
2929
if(traceOut.hoveron !== 'fills') coerce('hovertemplate');
3030

31+
if(subTypes.hasMarkers(traceOut)) {
32+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
33+
}
34+
3135
if(subTypes.hasLines(traceOut)) {
3236
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {backoff: true});
3337
handleLineShapeDefaults(traceIn, traceOut, coerce);
3438
coerce('connectgaps');
3539
}
3640

37-
if(subTypes.hasMarkers(traceOut)) {
38-
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
39-
}
40-
4141
if(subTypes.hasText(traceOut)) {
4242
coerce('texttemplate');
4343
handleTextDefaults(traceIn, traceOut, layout, coerce);

src/traces/scatterternary/defaults.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,16 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
5555
var defaultMode = len < constants.PTS_LINESONLY ? 'lines+markers' : 'lines';
5656
coerce('mode', defaultMode);
5757

58+
if(subTypes.hasMarkers(traceOut)) {
59+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
60+
}
61+
5862
if(subTypes.hasLines(traceOut)) {
5963
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {backoff: true});
6064
handleLineShapeDefaults(traceIn, traceOut, coerce);
6165
coerce('connectgaps');
6266
}
6367

64-
if(subTypes.hasMarkers(traceOut)) {
65-
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {gradient: true});
66-
}
67-
6868
if(subTypes.hasText(traceOut)) {
6969
coerce('texttemplate');
7070
handleTextDefaults(traceIn, traceOut, layout, coerce);

test/jasmine/tests/toimage_test.js

+77
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,83 @@ describe('Plotly.toImage', function() {
431431
.then(done, done.fail);
432432
});
433433

434+
[
435+
'scatter3d',
436+
'scattergl',
437+
'scatter'
438+
].forEach(function(type) {
439+
it('import & export arrayOk marker.color and marker.size for ' + type, function(done) {
440+
var is3D = type === 'scatter3d';
441+
442+
var allX = new Int16Array([-100, 200, -300, 400]);
443+
var allY = new Uint16Array([100, 200, 300, 400]);
444+
var allZ = new Int8Array([-120, -60, 0, 60]);
445+
var allS = new Uint8ClampedArray([0, 60, 120, 240]);
446+
var allC = new Uint8Array([0, 60, 120, 240]);
447+
448+
var x = b64encodeTypedArray(allX);
449+
var y = b64encodeTypedArray(allY);
450+
var z = b64encodeTypedArray(allZ);
451+
var s = b64encodeTypedArray(allS);
452+
var c = b64encodeTypedArray(allC);
453+
454+
Plotly.newPlot(gd, [{
455+
type: type,
456+
x: {bdata: x, dtype: 'i2'},
457+
y: {bdata: y, dtype: 'u2'},
458+
z: {bdata: z, dtype: 'i1'},
459+
marker: {
460+
color: {bdata: c, dtype: 'u1'},
461+
size: {bdata: s, dtype: 'c1'}
462+
}
463+
}])
464+
.then(function(gd) {
465+
var trace = gd._fullData[0];
466+
467+
expect(trace.visible).toEqual(true);
468+
469+
expect(trace.x.slice()).toEqual(allX);
470+
expect(trace.y.slice()).toEqual(allY);
471+
if(is3D) expect(trace.z.slice()).toEqual(allZ);
472+
expect(trace.marker.size.slice()).toEqual(allS);
473+
expect(trace.marker.color.slice()).toEqual(allC);
474+
expect(trace.line.color).toEqual('#1f77b4');
475+
476+
return Plotly.toImage(gd, imgOpts);
477+
})
478+
.then(function(fig) {
479+
var trace = JSON.parse(fig).data[0];
480+
481+
expect(trace.visible).toEqual(true);
482+
483+
expect(trace.x.bdata).toEqual('nP/IANT+kAE=');
484+
expect(trace.x.dtype).toEqual('i2');
485+
expect(trace.x.shape).toEqual('4');
486+
487+
expect(trace.y.bdata).toEqual('ZADIACwBkAE=');
488+
expect(trace.y.dtype).toEqual('u2');
489+
expect(trace.y.shape).toEqual('4');
490+
491+
if(is3D) {
492+
expect(trace.z.bdata).toEqual('iMQAPA==');
493+
expect(trace.z.dtype).toEqual('i1');
494+
expect(trace.z.shape).toEqual('4');
495+
}
496+
497+
expect(trace.marker.size.bdata).toEqual('ADx48A==');
498+
expect(trace.marker.size.dtype).toEqual('c1');
499+
expect(trace.marker.size.shape).toEqual('4');
500+
501+
expect(trace.marker.color.bdata).toEqual('ADx48A==');
502+
expect(trace.marker.color.dtype).toEqual('u1');
503+
expect(trace.marker.color.shape).toEqual('4');
504+
505+
expect(trace.marker.colorscale).toBeDefined();
506+
})
507+
.then(done, done.fail);
508+
});
509+
});
510+
434511
it('export computed margins', function(done) {
435512
Plotly.toImage(pieAutoMargin, imgOpts)
436513
.then(function(fig) {

0 commit comments

Comments
 (0)