Skip to content

Commit 5d35fd6

Browse files
committed
Merge pull request #255 from plotly/emit-doubleclick
Add doubleclick events
2 parents 7b0036e + 90edb18 commit 5d35fd6

File tree

6 files changed

+272
-38
lines changed

6 files changed

+272
-38
lines changed

src/plots/cartesian/graph_interact.js

+1
Original file line numberDiff line numberDiff line change
@@ -1822,6 +1822,7 @@ function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
18221822
}
18231823
}
18241824

1825+
gd.emit('plotly_doubleclick', null);
18251826
Plotly.relayout(gd, attrs);
18261827
}
18271828

src/plots/cartesian/select.js

+2
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) {
171171
searchInfo = searchTraces[i];
172172
searchInfo.selectPoints(searchInfo, false);
173173
}
174+
175+
gd.emit('plotly_deselect', null);
174176
}
175177
else {
176178
dragOptions.gd.emit('plotly_selected', eventData);

test/jasmine/tests/click_test.js

+56-21
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,62 @@
11
var Plotly = require('@lib/index');
22
var Lib = require('@src/lib');
3+
var DBLCLICKDELAY = require('@src/plots/cartesian/constants').DBLCLICKDELAY;
34

45
var createGraphDiv = require('../assets/create_graph_div');
56
var destroyGraphDiv = require('../assets/destroy_graph_div');
67
var mouseEvent = require('../assets/mouse_event');
78

89

9-
describe('click event', function() {
10-
var mock = require('@mocks/14.json');
10+
describe('click interactions', function() {
11+
var mock = require('@mocks/14.json'),
12+
mockCopy = Lib.extendDeep({}, mock),
13+
gd;
1114

12-
describe('event data', function() {
13-
var mockCopy = Lib.extendDeep({}, mock),
14-
clientX = 351,
15-
clientY = 223,
16-
gd;
15+
var pointPos = [351, 223],
16+
blankPos = [70, 363];
1717

18-
function click() {
19-
mouseEvent('mousemove', clientX, clientY);
20-
mouseEvent('mousedown', clientX, clientY);
21-
mouseEvent('mouseup', clientX, clientY);
22-
}
18+
afterEach(destroyGraphDiv);
2319

24-
beforeEach(function(done) {
25-
gd = createGraphDiv();
20+
// cartesian click events events use the hover data
21+
// from the mousemove events and then simulate
22+
// a click event on mouseup
23+
function click(x, y) {
24+
mouseEvent('mousemove', x, y);
25+
mouseEvent('mousedown', x, y);
26+
mouseEvent('mouseup', x, y);
27+
}
2628

27-
Plotly.plot(gd, mockCopy.data, mockCopy.layout)
28-
.then(done);
29-
});
29+
function doubleClick(x, y, cb) {
30+
click(x, y);
31+
setTimeout(function() {
32+
click(x, y);
33+
cb();
34+
}, DBLCLICKDELAY / 2);
35+
}
3036

31-
afterEach(destroyGraphDiv);
37+
beforeEach(function(done) {
38+
gd = createGraphDiv();
3239

33-
it('should contain the correct fields', function() {
34-
var futureData;
40+
Plotly.plot(gd, mockCopy.data, mockCopy.layout)
41+
.then(done);
42+
});
43+
44+
describe('click events', function() {
45+
var futureData;
3546

47+
beforeEach(function() {
3648
gd.on('plotly_click', function(data) {
3749
futureData = data;
3850
});
51+
});
3952

40-
click();
53+
it('should not be trigged when not on data points', function() {
54+
click(blankPos[0], blankPos[1]);
55+
expect(futureData).toBe(undefined);
56+
});
4157

58+
it('should contain the correct fields', function() {
59+
click(pointPos[0], pointPos[1]);
4260
expect(futureData.points.length).toEqual(1);
4361

4462
var pt = futureData.points[0];
@@ -52,4 +70,21 @@ describe('click event', function() {
5270
expect(pt.y).toEqual(2.125);
5371
});
5472
});
73+
74+
describe('double click events', function() {
75+
var futureData;
76+
77+
beforeEach(function() {
78+
gd.on('plotly_doubleclick', function(data) {
79+
futureData = data;
80+
});
81+
});
82+
83+
it('should return null', function(done) {
84+
doubleClick(pointPos[0], pointPos[1], function() {
85+
expect(futureData).toBe(null);
86+
done();
87+
});
88+
});
89+
});
5590
});

test/jasmine/tests/plot_promise_test.js

+3-17
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ var Events = require('@src/lib/events');
33
var createGraphDiv = require('../assets/create_graph_div');
44
var destroyGraphDiv = require('../assets/destroy_graph_div');
55

6+
67
describe('Plotly.___ methods', function() {
78
'use strict';
89

10+
afterEach(destroyGraphDiv);
11+
912
describe('Plotly.plot promise', function() {
1013
var promise,
1114
promiseGd;
@@ -20,7 +23,6 @@ describe('Plotly.___ methods', function() {
2023
done();
2124
});
2225
});
23-
afterEach(destroyGraphDiv);
2426

2527
it('should be returned with the graph div as an argument', function() {
2628
expect(promiseGd).toBeDefined();
@@ -54,7 +56,6 @@ describe('Plotly.___ methods', function() {
5456
});
5557
});
5658

57-
afterEach(destroyGraphDiv);
5859

5960
it('should be rejected when plotly_beforeplot event handlers return false', function() {
6061
expect(promiseRejected).toBe(true);
@@ -81,7 +82,6 @@ describe('Plotly.___ methods', function() {
8182
});
8283
});
8384

84-
afterEach(destroyGraphDiv);
8585

8686
it('should reject the promise when graph is being dragged', function() {
8787
expect(promiseRejected).toBe(true);
@@ -105,7 +105,6 @@ describe('Plotly.___ methods', function() {
105105
done();
106106
});
107107
});
108-
afterEach(destroyGraphDiv);
109108

110109
it('should be returned with the graph div as an argument', function() {
111110
expect(promiseGd).toBeDefined();
@@ -129,7 +128,6 @@ describe('Plotly.___ methods', function() {
129128
done();
130129
});
131130
});
132-
afterEach(destroyGraphDiv);
133131

134132
it('should be returned with the graph div as an argument', function() {
135133
expect(promiseGd).toBeDefined();
@@ -156,7 +154,6 @@ describe('Plotly.___ methods', function() {
156154
done();
157155
});
158156
});
159-
afterEach(destroyGraphDiv);
160157

161158
it('should be returned with the graph div as an argument', function() {
162159
expect(promiseGd).toBeDefined();
@@ -183,7 +180,6 @@ describe('Plotly.___ methods', function() {
183180
done();
184181
});
185182
});
186-
afterEach(destroyGraphDiv);
187183

188184
it('should be returned with the graph div as an argument', function() {
189185
expect(promiseGd).toBeDefined();
@@ -210,7 +206,6 @@ describe('Plotly.___ methods', function() {
210206
done();
211207
});
212208
});
213-
afterEach(destroyGraphDiv);
214209

215210
it('should be returned with the graph div as an argument', function() {
216211
expect(promiseGd).toBeDefined();
@@ -237,7 +232,6 @@ describe('Plotly.___ methods', function() {
237232
done();
238233
});
239234
});
240-
afterEach(destroyGraphDiv);
241235

242236
it('should be returned with the graph div as an argument', function() {
243237
expect(promiseGd).toBeDefined();
@@ -264,7 +258,6 @@ describe('Plotly.___ methods', function() {
264258
done();
265259
});
266260
});
267-
afterEach(destroyGraphDiv);
268261

269262
it('should be returned with the graph div as an argument', function() {
270263
expect(promiseGd).toBeDefined();
@@ -294,7 +287,6 @@ describe('Plotly.___ methods', function() {
294287
done();
295288
});
296289
});
297-
afterEach(destroyGraphDiv);
298290

299291
it('should be returned with the graph div as an argument', function() {
300292
expect(promiseGd).toBeDefined();
@@ -321,7 +313,6 @@ describe('Plotly.___ methods', function() {
321313
done();
322314
});
323315
});
324-
afterEach(destroyGraphDiv);
325316

326317
it('should be returned with the graph div as an argument', function() {
327318
expect(promiseGd).toBeDefined();
@@ -348,7 +339,6 @@ describe('Plotly.___ methods', function() {
348339
done();
349340
});
350341
});
351-
afterEach(destroyGraphDiv);
352342

353343
it('should be rejected when the attribute is missing', function() {
354344
expect(promiseRejected).toBe(true);
@@ -373,7 +363,6 @@ describe('Plotly.___ methods', function() {
373363
done();
374364
});
375365
});
376-
afterEach(destroyGraphDiv);
377366

378367
it('should be returned with the graph div as an argument', function() {
379368
expect(promiseGd).toBeDefined();
@@ -401,7 +390,6 @@ describe('Plotly.___ methods', function() {
401390
done();
402391
});
403392
});
404-
afterEach(destroyGraphDiv);
405393

406394
it('should be returned with the graph div as an argument', function() {
407395
expect(promiseGd).toBeDefined();
@@ -430,7 +418,6 @@ describe('Plotly.___ methods', function() {
430418
done();
431419
});
432420
});
433-
afterEach(destroyGraphDiv);
434421

435422
it('should be returned with the graph div unchanged when the framework is polar', function() {
436423
expect(promiseGd).toBeDefined();
@@ -457,7 +444,6 @@ describe('Plotly.___ methods', function() {
457444
done();
458445
});
459446
});
460-
afterEach(destroyGraphDiv);
461447

462448
it('should be rejected when the attribute is missing', function() {
463449
expect(promiseRejected).toBe(true);

test/jasmine/tests/register_test.js

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
11
var Plotly = require('@lib/index');
22

33
describe('the register function', function() {
4+
'use strict';
5+
6+
var Plots = Plotly.Plots;
7+
8+
beforeEach(function() {
9+
this.modulesKeys = Object.keys(Plots.modules);
10+
this.allTypesKeys = Object.keys(Plots.allTypes);
11+
this.allCategoriesKeys = Object.keys(Plots.allCategories);
12+
});
13+
14+
afterEach(function() {
15+
function revertObj(obj, initialKeys) {
16+
Object.keys(obj).forEach(function(k) {
17+
if(initialKeys.indexOf(k) === -1) delete obj[k];
18+
});
19+
}
20+
21+
revertObj(Plots.modules, this.modulesKeys);
22+
revertObj(Plots.allTypes, this.allTypesKeys);
23+
revertObj(Plots.allCategories, this.allCategoriesKeys);
24+
});
425

526
it('should throw an error when no argument is given', function() {
627
expect(function() {

0 commit comments

Comments
 (0)