Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add doubleclick events #255

Merged
merged 15 commits into from
Feb 24, 2016
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/plots/cartesian/graph_interact.js
Original file line number Diff line number Diff line change
Expand Up @@ -1821,6 +1821,7 @@ function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
}
}

gd.emit('plotly_doubleclick', null);
Plotly.relayout(gd, attrs);
}

Expand Down
2 changes: 2 additions & 0 deletions src/plots/cartesian/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) {
searchInfo = searchTraces[i];
searchInfo.selectPoints(searchInfo, false);
}

gd.emit('plotly_doubleclick', null);
}
else {
dragOptions.gd.emit('plotly_selected', eventData);
Expand Down
84 changes: 52 additions & 32 deletions test/jasmine/tests/click_test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var Plotly = require('@lib/index');
var Lib = require('@src/lib');
var DBLCLICKDELAY = require('@src/plots/cartesian/constants').DBLCLICKDELAY;

var createGraphDiv = require('../assets/create_graph_div');
var destroyGraphDiv = require('../assets/destroy_graph_div');
Expand All @@ -9,47 +10,66 @@ var mouseEvent = require('../assets/mouse_event');
describe('click event', function() {
var mock = require('@mocks/14.json');

describe('event data', function() {
var mockCopy = Lib.extendDeep({}, mock),
clientX = 351,
clientY = 223,
gd;
afterEach(destroyGraphDiv);

function click() {
mouseEvent('mousemove', clientX, clientY);
mouseEvent('mousedown', clientX, clientY);
mouseEvent('mouseup', clientX, clientY);
}
var mockCopy = Lib.extendDeep({}, mock),
clientX = 351,
clientY = 223,
gd;

beforeEach(function(done) {
gd = createGraphDiv();
function click() {
mouseEvent('mousemove', clientX, clientY);
mouseEvent('mousedown', clientX, clientY);
mouseEvent('mouseup', clientX, clientY);
}

Plotly.plot(gd, mockCopy.data, mockCopy.layout)
.then(done);
function doubleClick(cb) {
click();
setTimeout(function() {
click();
cb();
}, DBLCLICKDELAY / 2);
}

beforeEach(function(done) {
gd = createGraphDiv();

Plotly.plot(gd, mockCopy.data, mockCopy.layout)
.then(done);
});

it('should contain the correct fields', function() {
var futureData;

gd.on('plotly_click', function(data) {
futureData = data;
});

afterEach(destroyGraphDiv);
click();

it('should contain the correct fields', function() {
var futureData;
expect(futureData.points.length).toEqual(1);

gd.on('plotly_click', function(data) {
futureData = data;
});
var pt = futureData.points[0];
expect(Object.keys(pt)).toEqual([
'data', 'fullData', 'curveNumber', 'pointNumber',
'x', 'y', 'xaxis', 'yaxis'
]);
expect(pt.curveNumber).toEqual(0);
expect(pt.pointNumber).toEqual(11);
expect(pt.x).toEqual(0.125);
expect(pt.y).toEqual(2.125);
});

click();
it('should trigger double click if two clicks are \'close\' together', function(done) {
var futureData;

gd.on('plotly_doubleclick', function(data) {
futureData = data;
});

expect(futureData.points.length).toEqual(1);

var pt = futureData.points[0];
expect(Object.keys(pt)).toEqual([
'data', 'fullData', 'curveNumber', 'pointNumber',
'x', 'y', 'xaxis', 'yaxis'
]);
expect(pt.curveNumber).toEqual(0);
expect(pt.pointNumber).toEqual(11);
expect(pt.x).toEqual(0.125);
expect(pt.y).toEqual(2.125);
doubleClick(function() {
expect(futureData).toBe(null);
done();
});
});
});
21 changes: 21 additions & 0 deletions test/jasmine/tests/register_test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
var Plotly = require('@lib/index');

describe('the register function', function() {
'use strict';

var Plots = Plotly.Plots;

beforeEach(function() {
this.modulesKeys = Object.keys(Plots.modules);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid using this here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

You're not a fan of the jasmine this ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually on second look, I'm ok with that. Didn't know that it was jasmine convention and that the this is cleared between specs.

this.allTypesKeys = Object.keys(Plots.allTypes);
this.allCategoriesKeys = Object.keys(Plots.allCategories);
});

afterEach(function() {
function revertObj(obj, initialKeys) {
Object.keys(obj).forEach(function(k) {
if(initialKeys.indexOf(k) === -1) delete obj[k];
});
}

revertObj(Plots.modules, this.modulesKeys);
revertObj(Plots.allTypes, this.allTypesKeys);
revertObj(Plots.allCategories, this.allCategoriesKeys);
});

it('should throw an error when no argument is given', function() {
expect(function() {
Expand Down
183 changes: 183 additions & 0 deletions test/jasmine/tests/select_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
var Plotly = require('@lib/index');
var Lib = require('@src/lib');
var DBLCLICKDELAY = require('@src/plots/cartesian/constants').DBLCLICKDELAY;

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


describe('select box and lasso', function() {
var mock = require('@mocks/14.json');

afterEach(destroyGraphDiv);

function drag(path) {
var len = path.length;

mouseEvent('mousemove', path[0][0], path[0][1]);
mouseEvent('mousedown', path[0][0], path[0][1]);

path.slice(1, len).forEach(function(pt) {
mouseEvent('mousemove', pt[0], pt[1]);
});

mouseEvent('mouseup', path[len - 1][0], path[len - 1][1]);
}

function click(x, y) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for using mousedown and mouseup over just click?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #176 (comment)

But yeah, I should mention why in the code too.

mouseEvent('mousemove', x, y);
mouseEvent('mousedown', x, y);
mouseEvent('mouseup', x, y);
}

function doubleClick(x, y, cb) {
click(x, y);
setTimeout(function() {
click(x, y);
cb();
}, DBLCLICKDELAY / 2);
}

function assertRange(actual, expected) {
var PRECISION = 4;

expect(actual.x[0]).toBeCloseTo(expected.x[0], PRECISION);
expect(actual.x[1]).toBeCloseTo(expected.x[1], PRECISION);
expect(actual.y[0]).toBeCloseTo(expected.y[0], PRECISION);
expect(actual.y[1]).toBeCloseTo(expected.y[1], PRECISION);
}

describe('select events', function() {
var mockCopy = Lib.extendDeep({}, mock);
mockCopy.layout.dragmode = 'select';

var gd;
beforeEach(function(done) {
gd = createGraphDiv();

Plotly.plot(gd, mockCopy.data, mockCopy.layout)
.then(done);
});

it('should trigger events', function(done) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add some comments as to the specifics of the test. It's not immediately clear what's being tested.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

var selectingCnt = 0,
selectingData;
gd.on('plotly_selecting', function(data) {
selectingCnt++;
selectingData = data;
});

var selectedCnt = 0,
selectedData;
gd.on('plotly_selected', function(data) {
selectedCnt++;
selectedData = data;
});

var doubleClickData;
gd.on('plotly_doubleclick', function(data) {
doubleClickData = data;
});

drag([[100, 200], [150, 200]]);

expect(selectingCnt).toEqual(1);
expect(selectingData.points).toEqual([{
curveNumber: 0,
pointNumber: 0,
x: 0.002,
y: 16.25
}, {
curveNumber: 0,
pointNumber: 1,
x: 0.004,
y: 12.5
}]);
assertRange(selectingData.range, {
x: [0.0019667582669138295, 0.004546754982054625],
y: [0.10209191961595454, 24.512223978291406]
});

expect(selectedCnt).toEqual(1);
expect(selectedData.points).toEqual([{
curveNumber: 0,
pointNumber: 0,
x: 0.002,
y: 16.25
}, {
curveNumber: 0,
pointNumber: 1,
x: 0.004,
y: 12.5
}]);
assertRange(selectedData.range, {
x: [0.0019667582669138295, 0.004546754982054625],
y: [0.10209191961595454, 24.512223978291406]
});

doubleClick(250, 200, function() {
expect(doubleClickData).toBe(null);
done();
});
});

});

describe('lasso events', function() {
var mockCopy = Lib.extendDeep({}, mock);
mockCopy.layout.dragmode = 'lasso';

var gd;
beforeEach(function(done) {
gd = createGraphDiv();

Plotly.plot(gd, mockCopy.data, mockCopy.layout)
.then(done);
});

it('should trigger events', function(done) {
var selectingCnt = 0,
selectingData;
gd.on('plotly_selecting', function(data) {
selectingCnt++;
selectingData = data;
});

var selectedCnt = 0,
selectedData;
gd.on('plotly_selected', function(data) {
selectedCnt++;
selectedData = data;
});

var doubleClickData;
gd.on('plotly_doubleclick', function(data) {
doubleClickData = data;
});

drag([[331, 178], [333, 246], [350, 250], [343, 176]]);

expect(selectingCnt).toEqual(3);
expect(selectingData.points).toEqual([{
curveNumber: 0,
pointNumber: 10,
x: 0.099,
y: 2.75
}]);

expect(selectedCnt).toEqual(1);
expect(selectedData.points).toEqual([{
curveNumber: 0,
pointNumber: 10,
x: 0.099,
y: 2.75
}]);

doubleClick(250, 200, function() {
expect(doubleClickData).toBe(null);
done();
});
});
});
});