Skip to content

Commit 77aaad2

Browse files
committed
Merge branch 'master' into fix-layout-animation
Conflicts: test/jasmine/tests/animate_test.js
2 parents 133b9d6 + 2ac3dd7 commit 77aaad2

File tree

15 files changed

+170
-52
lines changed

15 files changed

+170
-52
lines changed

circle.yml

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ dependencies:
1717
- npm run cibuild
1818
- npm run pretest
1919
- eval $(node tasks/docker.js setup)
20+
- npm ls
2021

2122
test:
2223
override:

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
"browserify-transform-tools": "^1.5.1",
9898
"deep-equal": "^1.0.1",
9999
"ecstatic": "^2.1.0",
100-
"eslint": "^3.5.0",
100+
"eslint": "^3.9.1",
101101
"falafel": "^2.0.0",
102102
"fs-extra": "^0.30.0",
103103
"fuse.js": "^2.2.0",

src/components/sliders/draw.js

+15
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,21 @@ function handleInput(gd, sliderGroup, sliderOpts, normalizedPosition, doTransiti
366366
}
367367

368368
function setActive(gd, sliderGroup, sliderOpts, index, doCallback, doTransition) {
369+
var previousActive = sliderOpts.active;
369370
sliderOpts._input.active = sliderOpts.active = index;
370371

371372
var step = sliderOpts.steps[sliderOpts.active];
372373

373374
sliderGroup.call(setGripPosition, sliderOpts, sliderOpts.active / (sliderOpts.steps.length - 1), doTransition);
374375
sliderGroup.call(drawCurrentValue, sliderOpts);
375376

377+
gd.emit('plotly_sliderchange', {
378+
slider: sliderOpts,
379+
step: sliderOpts.steps[sliderOpts.active],
380+
interaction: doCallback,
381+
previousActive: previousActive
382+
});
383+
376384
if(step && step.method && doCallback) {
377385
if(sliderGroup._nextMethod) {
378386
// If we've already queued up an update, just overwrite it with the most recent:
@@ -399,6 +407,8 @@ function attachGripEvents(item, gd, sliderGroup, sliderOpts) {
399407
var $gd = d3.select(gd);
400408

401409
item.on('mousedown', function() {
410+
gd.emit('plotly_sliderstart', {slider: sliderOpts});
411+
402412
var grip = sliderGroup.select('.' + constants.gripRectClass);
403413

404414
d3.event.stopPropagation();
@@ -419,6 +429,11 @@ function attachGripEvents(item, gd, sliderGroup, sliderOpts) {
419429
grip.call(Color.fill, sliderOpts.bgcolor);
420430
$gd.on('mouseup', null);
421431
$gd.on('mousemove', null);
432+
433+
gd.emit('plotly_sliderend', {
434+
slider: sliderOpts,
435+
step: sliderOpts.steps[sliderOpts.active]
436+
});
422437
});
423438
});
424439
}

src/components/updatemenus/draw.js

+2
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ function drawButtons(gd, gHeader, gButton, menuOpts) {
299299
setActive(gd, menuOpts, buttonOpts, gHeader, gButton, buttonIndex);
300300

301301
Plots.executeAPICommand(gd, buttonOpts.method, buttonOpts.args);
302+
303+
gd.emit('plotly_buttonclicked', {menu: menuOpts, button: buttonOpts, active: menuOpts.active});
302304
});
303305

304306
button.on('mouseover', function() {

src/plot_api/plot_api.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -2005,7 +2005,7 @@ function _relayout(gd, aobj) {
20052005
*/
20062006
else if(['hovermode', 'dragmode'].indexOf(ai) !== -1) flags.domodebar = true;
20072007
else if(['hovermode', 'dragmode', 'height',
2008-
'width', 'autosize'].indexOf(ai) === -1) {
2008+
'width', 'autosize'].indexOf(ai) === -1) {
20092009
flags.doplot = true;
20102010
}
20112011

@@ -2416,6 +2416,8 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
24162416
for(i = 0; i < trans._frames.length; i++) {
24172417
frame = trans._frames[i];
24182418

2419+
if(!frame) continue;
2420+
24192421
if(allFrames || frame.group === frameOrGroupNameOrFrameList) {
24202422
frameList.push({
24212423
type: 'byname',
@@ -2579,7 +2581,7 @@ Plotly.addFrames = function(gd, frameList, indices) {
25792581
if(_hash[frame.name]) {
25802582
// If frame is present, overwrite its definition:
25812583
for(j = 0; j < _frames.length; j++) {
2582-
if(_frames[j].name === frame.name) break;
2584+
if((_frames[j] || {}).name === frame.name) break;
25832585
}
25842586
ops.push({type: 'replace', index: j, value: frame});
25852587
revops.unshift({type: 'replace', index: j, value: _frames[j]});

src/plots/cartesian/tick_label_defaults.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ module.exports = function handleTickLabelDefaults(containerIn, containerOut, coe
6767
*/
6868
function getShowAttrDflt(containerIn) {
6969
var showAttrsAll = ['showexponent',
70-
'showtickprefix',
71-
'showticksuffix'],
70+
'showtickprefix',
71+
'showticksuffix'],
7272
showAttrs = showAttrsAll.filter(function(a) {
7373
return containerIn[a] !== undefined;
7474
}),

src/plots/geo/set_scale.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ function makeRangeBox(lon0, lat0, lon1, lat1) {
127127
return {
128128
type: 'Polygon',
129129
coordinates: [
130-
[ [lon0, lat0],
130+
[ [lon0, lat0],
131131
[lon0, lat1],
132132
[lon0 + dlon4, lat1],
133133
[lon0 + 2 * dlon4, lat1],

src/plots/plots.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ plots.modifyFrames = function(gd, operations) {
14371437
break;*/
14381438
case 'replace':
14391439
frame = op.value;
1440-
var oldName = _frames[op.index].name;
1440+
var oldName = (_frames[op.index] || {}).name;
14411441
var newName = frame.name;
14421442
_frames[op.index] = _hash[newName] = frame;
14431443

src/traces/contour/plot.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ function makePath(pi, loc, edgeflag) {
320320
// even # of pts - average central two
321321
else {
322322
newpt = [(getpt(ptavg)[0] + getpt(ptavg + 1)[0]) / 2,
323-
(getpt(ptavg)[1] + getpt(ptavg + 1)[1]) / 2];
323+
(getpt(ptavg)[1] + getpt(ptavg + 1)[1]) / 2];
324324
}
325325

326326
pts.splice(cnt2 + 1, cnt - cnt2 + 1, newpt);
@@ -458,12 +458,12 @@ function getInterpPx(pi, loc, step) {
458458
if(step[1]) {
459459
var dx = (pi.level - zxy) / (pi.z[locy][locx + 1] - zxy);
460460
return [xa.c2p((1 - dx) * pi.x[locx] + dx * pi.x[locx + 1], true),
461-
ya.c2p(pi.y[locy], true)];
461+
ya.c2p(pi.y[locy], true)];
462462
}
463463
else {
464464
var dy = (pi.level - zxy) / (pi.z[locy + 1][locx] - zxy);
465465
return [xa.c2p(pi.x[locx], true),
466-
ya.c2p((1 - dy) * pi.y[locy] + dy * pi.y[locy + 1], true)];
466+
ya.c2p((1 - dy) * pi.y[locy] + dy * pi.y[locy + 1], true)];
467467
}
468468
}
469469

src/traces/surface/convert.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ function refine(coords) {
151151
var padImg = padField(coords[i]);
152152
var scaledImg = ndarray(new Float32Array(nsize), nshape);
153153
homography(scaledImg, padImg, [scaleF, 0, 0,
154-
0, scaleF, 0,
155-
0, 0, 1]);
154+
0, scaleF, 0,
155+
0, 0, 1]);
156156
coords[i] = scaledImg;
157157
}
158158

test/jasmine/tests/animate_test.js

+9
Original file line numberDiff line numberDiff line change
@@ -693,4 +693,13 @@ describe('Animate API details', function() {
693693
expect(gd._fullLayout._currentFrame).toEqual('frame0');
694694
}).catch(fail).then(done);
695695
});
696+
697+
it('null frames should not break everything', function(done) {
698+
gd._transitionData._frames.push(null);
699+
700+
Plotly.animate(gd, null, {
701+
frame: {duration: 0},
702+
transition: {duration: 0}
703+
}).catch(fail).then(done);
704+
});
696705
});

test/jasmine/tests/heatmap_test.js

+37-37
Original file line numberDiff line numberDiff line change
@@ -452,43 +452,43 @@ describe('heatmap plot', function() {
452452

453453
argumentsWithPadding = getContextStub.fillRect.calls.allArgs().slice(getContextStub.fillRect.calls.allArgs().length - 9);
454454
expect(argumentsWithPadding).toEqual([
455-
[argumentsWithoutPadding[0][0],
456-
argumentsWithoutPadding[0][1] + edgeYGap,
457-
argumentsWithoutPadding[0][2] - edgeXGap,
458-
argumentsWithoutPadding[0][3] - edgeYGap],
459-
[argumentsWithoutPadding[1][0] + centerXGap,
460-
argumentsWithoutPadding[1][1] + edgeYGap,
461-
argumentsWithoutPadding[1][2] - edgeXGap,
462-
argumentsWithoutPadding[1][3] - edgeYGap],
463-
[argumentsWithoutPadding[2][0] + edgeXGap,
464-
argumentsWithoutPadding[2][1] + edgeYGap,
465-
argumentsWithoutPadding[2][2] - edgeXGap,
466-
argumentsWithoutPadding[2][3] - edgeYGap],
467-
[argumentsWithoutPadding[3][0],
468-
argumentsWithoutPadding[3][1] + centerYGap,
469-
argumentsWithoutPadding[3][2] - edgeXGap,
470-
argumentsWithoutPadding[3][3] - edgeYGap],
471-
[argumentsWithoutPadding[4][0] + centerXGap,
472-
argumentsWithoutPadding[4][1] + centerYGap,
473-
argumentsWithoutPadding[4][2] - edgeXGap,
474-
argumentsWithoutPadding[4][3] - edgeYGap],
475-
[argumentsWithoutPadding[5][0] + edgeXGap,
476-
argumentsWithoutPadding[5][1] + centerYGap,
477-
argumentsWithoutPadding[5][2] - edgeXGap,
478-
argumentsWithoutPadding[5][3] - edgeYGap],
479-
[argumentsWithoutPadding[6][0],
480-
argumentsWithoutPadding[6][1],
481-
argumentsWithoutPadding[6][2] - edgeXGap,
482-
argumentsWithoutPadding[6][3] - edgeYGap],
483-
[argumentsWithoutPadding[7][0] + centerXGap,
484-
argumentsWithoutPadding[7][1],
485-
argumentsWithoutPadding[7][2] - edgeXGap,
486-
argumentsWithoutPadding[7][3] - edgeYGap],
487-
[argumentsWithoutPadding[8][0] + edgeXGap,
488-
argumentsWithoutPadding[8][1],
489-
argumentsWithoutPadding[8][2] - edgeXGap,
490-
argumentsWithoutPadding[8][3] - edgeYGap
491-
]]);
455+
[argumentsWithoutPadding[0][0],
456+
argumentsWithoutPadding[0][1] + edgeYGap,
457+
argumentsWithoutPadding[0][2] - edgeXGap,
458+
argumentsWithoutPadding[0][3] - edgeYGap],
459+
[argumentsWithoutPadding[1][0] + centerXGap,
460+
argumentsWithoutPadding[1][1] + edgeYGap,
461+
argumentsWithoutPadding[1][2] - edgeXGap,
462+
argumentsWithoutPadding[1][3] - edgeYGap],
463+
[argumentsWithoutPadding[2][0] + edgeXGap,
464+
argumentsWithoutPadding[2][1] + edgeYGap,
465+
argumentsWithoutPadding[2][2] - edgeXGap,
466+
argumentsWithoutPadding[2][3] - edgeYGap],
467+
[argumentsWithoutPadding[3][0],
468+
argumentsWithoutPadding[3][1] + centerYGap,
469+
argumentsWithoutPadding[3][2] - edgeXGap,
470+
argumentsWithoutPadding[3][3] - edgeYGap],
471+
[argumentsWithoutPadding[4][0] + centerXGap,
472+
argumentsWithoutPadding[4][1] + centerYGap,
473+
argumentsWithoutPadding[4][2] - edgeXGap,
474+
argumentsWithoutPadding[4][3] - edgeYGap],
475+
[argumentsWithoutPadding[5][0] + edgeXGap,
476+
argumentsWithoutPadding[5][1] + centerYGap,
477+
argumentsWithoutPadding[5][2] - edgeXGap,
478+
argumentsWithoutPadding[5][3] - edgeYGap],
479+
[argumentsWithoutPadding[6][0],
480+
argumentsWithoutPadding[6][1],
481+
argumentsWithoutPadding[6][2] - edgeXGap,
482+
argumentsWithoutPadding[6][3] - edgeYGap],
483+
[argumentsWithoutPadding[7][0] + centerXGap,
484+
argumentsWithoutPadding[7][1],
485+
argumentsWithoutPadding[7][2] - edgeXGap,
486+
argumentsWithoutPadding[7][3] - edgeYGap],
487+
[argumentsWithoutPadding[8][0] + edgeXGap,
488+
argumentsWithoutPadding[8][1],
489+
argumentsWithoutPadding[8][2] - edgeXGap,
490+
argumentsWithoutPadding[8][3] - edgeYGap
491+
]]);
492492
done();
493493
});
494494
});

test/jasmine/tests/lib_test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ describe('Test lib.js:', function() {
695695
var colVal = 'red',
696696
sizeVal = 14,
697697
attrs = {testMarker: {testColor: {valType: 'color', dflt: 'rgba(0, 0, 0, 0)'},
698-
testSize: {valType: 'number', dflt: 20}}},
698+
testSize: {valType: 'number', dflt: 20}}},
699699
obj = {testMarker: {testColor: colVal, testSize: sizeVal}},
700700
outObj = {},
701701
colOut = coerce2(obj, outObj, attrs, 'testMarker.testColor'),
@@ -711,7 +711,7 @@ describe('Test lib.js:', function() {
711711
var colVal = 'r',
712712
sizeVal = 'aaaaah!',
713713
attrs = {testMarker: {testColor: {valType: 'color', dflt: 'rgba(0, 0, 0, 0)'},
714-
testSize: {valType: 'number', dflt: 20}}},
714+
testSize: {valType: 'number', dflt: 20}}},
715715
obj = {testMarker: {testColor: colVal, testSize: sizeVal}},
716716
outObj = {},
717717
colOut = coerce2(obj, outObj, attrs, 'testMarker.testColor'),
@@ -727,7 +727,7 @@ describe('Test lib.js:', function() {
727727
var colVal = null,
728728
sizeVal = null,
729729
attrs = {testMarker: {testColor: {valType: 'color', dflt: 'rgba(0, 0, 0, 0)'},
730-
testSize: {valType: 'number', dflt: 20}}},
730+
testSize: {valType: 'number', dflt: 20}}},
731731
obj = {testMarker: {testColor: colVal, testSize: sizeVal}},
732732
outObj = {},
733733
colOut = coerce2(obj, outObj, attrs, 'testMarker.testColor'),

test/jasmine/tests/sliders_test.js

+64
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,70 @@ describe('sliders interactions', function() {
319319
}, 100);
320320
});
321321

322+
it('should issue events on interaction', function(done) {
323+
var cntStart = 0;
324+
var cntInteraction = 0;
325+
var cntNonInteraction = 0;
326+
var cntEnd = 0;
327+
328+
gd.on('plotly_sliderstart', function() {
329+
cntStart++;
330+
}).on('plotly_sliderchange', function(datum) {
331+
if(datum.interaction) {
332+
cntInteraction++;
333+
} else {
334+
cntNonInteraction++;
335+
}
336+
}).on('plotly_sliderend', function() {
337+
cntEnd++;
338+
});
339+
340+
function assertEventCounts(starts, interactions, noninteractions, ends) {
341+
expect(
342+
[cntStart, cntInteraction, cntNonInteraction, cntEnd]
343+
).toEqual(
344+
[starts, interactions, noninteractions, ends]
345+
);
346+
}
347+
348+
assertEventCounts(0, 0, 0, 0);
349+
350+
var firstGroup = gd._fullLayout._infolayer.select('.' + constants.railTouchRectClass);
351+
var railNode = firstGroup.node();
352+
var touchRect = railNode.getBoundingClientRect();
353+
354+
// Dispatch a click on the right side of the bar:
355+
railNode.dispatchEvent(new MouseEvent('mousedown', {
356+
clientY: touchRect.top + 5,
357+
clientX: touchRect.left + touchRect.width - 5,
358+
}));
359+
360+
setTimeout(function() {
361+
// One slider received a mousedown, one received an interaction, and one received a change:
362+
assertEventCounts(1, 1, 1, 0);
363+
364+
// Drag to the left side:
365+
gd.dispatchEvent(new MouseEvent('mousemove', {
366+
clientY: touchRect.top + 5,
367+
clientX: touchRect.left + 5,
368+
}));
369+
370+
setTimeout(function() {
371+
// On move, now to changes for the each slider, and no ends:
372+
assertEventCounts(1, 2, 2, 0);
373+
374+
gd.dispatchEvent(new MouseEvent('mouseup'));
375+
376+
setTimeout(function() {
377+
// Now an end:
378+
assertEventCounts(1, 2, 2, 1);
379+
380+
done();
381+
}, 50);
382+
}, 50);
383+
}, 50);
384+
});
385+
322386
function assertNodeCount(query, cnt) {
323387
expect(d3.selectAll(query).size()).toEqual(cnt);
324388
}

test/jasmine/tests/updatemenus_test.js

+25
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,31 @@ describe('update menus interactions', function() {
380380
});
381381
});
382382

383+
it('should emit an event on button click', function(done) {
384+
var clickCnt = 0;
385+
var data = [];
386+
gd.on('plotly_buttonclicked', function(datum) {
387+
data.push(datum);
388+
clickCnt++;
389+
});
390+
391+
click(selectHeader(0)).then(function() {
392+
expect(clickCnt).toEqual(0);
393+
394+
return click(selectButton(2));
395+
}).then(function() {
396+
expect(clickCnt).toEqual(1);
397+
expect(data.length).toEqual(1);
398+
expect(data[0].active).toEqual(2);
399+
400+
return click(selectButton(1));
401+
}).then(function() {
402+
expect(clickCnt).toEqual(2);
403+
expect(data.length).toEqual(2);
404+
expect(data[1].active).toEqual(1);
405+
}).catch(fail).then(done);
406+
});
407+
383408
it('should apply update on button click', function(done) {
384409
var header0 = selectHeader(0),
385410
header1 = selectHeader(1);

0 commit comments

Comments
 (0)