From 87ccf58156aa517b378d6c39c9124384ae3afabf Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Wed, 9 Nov 2016 13:49:37 -0500 Subject: [PATCH 1/4] Add slider events --- src/components/sliders/draw.js | 23 +++++++++++- test/jasmine/tests/sliders_test.js | 56 ++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/components/sliders/draw.js b/src/components/sliders/draw.js index 953d131ad17..06bfd2ccbd5 100644 --- a/src/components/sliders/draw.js +++ b/src/components/sliders/draw.js @@ -361,11 +361,16 @@ function handleInput(gd, sliderGroup, sliderOpts, normalizedPosition, doTransiti var quantizedPosition = Math.round(normalizedPosition * (sliderOpts.steps.length - 1)); if(quantizedPosition !== sliderOpts.active) { + var ret = {previousActive: sliderOpts.active}; + setActive(gd, sliderGroup, sliderOpts, quantizedPosition, true, doTransition); + + return ret; } } function setActive(gd, sliderGroup, sliderOpts, index, doCallback, doTransition) { + var previousActive = sliderOpts.active; sliderOpts._input.active = sliderOpts.active = index; var step = sliderOpts.steps[sliderOpts.active]; @@ -373,6 +378,11 @@ function setActive(gd, sliderGroup, sliderOpts, index, doCallback, doTransition) sliderGroup.call(setGripPosition, sliderOpts, sliderOpts.active / (sliderOpts.steps.length - 1), doTransition); sliderGroup.call(drawCurrentValue, sliderOpts); + gd.emit('plotly_sliderchange', { + slider: sliderOpts, + previousActive: previousActive + }); + if(step && step.method && doCallback) { if(sliderGroup._nextMethod) { // If we've already queued up an update, just overwrite it with the most recent: @@ -405,13 +415,22 @@ function attachGripEvents(item, gd, sliderGroup, sliderOpts) { d3.event.preventDefault(); grip.call(Color.fill, sliderOpts.activebgcolor); + gd.emit('plotly_sliderdragstart', {slider: sliderOpts}); + var normalizedPosition = positionToNormalizedValue(sliderOpts, d3.mouse(node)[0]); handleInput(gd, sliderGroup, sliderOpts, normalizedPosition, true); sliderOpts._dragging = true; $gd.on('mousemove', function() { var normalizedPosition = positionToNormalizedValue(sliderOpts, d3.mouse(node)[0]); - handleInput(gd, sliderGroup, sliderOpts, normalizedPosition, false); + var changes = handleInput(gd, sliderGroup, sliderOpts, normalizedPosition, false); + + if(changes) { + gd.emit('plotly_sliderdragmove', { + slider: sliderOpts, + previousActive: changes.previousActive + }); + } }); $gd.on('mouseup', function() { @@ -419,6 +438,8 @@ function attachGripEvents(item, gd, sliderGroup, sliderOpts) { grip.call(Color.fill, sliderOpts.bgcolor); $gd.on('mouseup', null); $gd.on('mousemove', null); + + gd.emit('plotly_sliderdragend', {slider: sliderOpts}); }); }); } diff --git a/test/jasmine/tests/sliders_test.js b/test/jasmine/tests/sliders_test.js index 1f7fa4b8a79..65b99c4589a 100644 --- a/test/jasmine/tests/sliders_test.js +++ b/test/jasmine/tests/sliders_test.js @@ -319,6 +319,62 @@ describe('sliders interactions', function() { }, 100); }); + it('should issue events on interaction', function(done) { + var cntStart = 0; + var cntMove = 0; + var cntEnd = 0; + var cntChange = 0; + + gd.on('plotly_sliderdragstart', function() { cntStart++; }); + gd.on('plotly_sliderdragmove', function() { cntMove++; }); + gd.on('plotly_sliderdragend', function() { cntEnd++; }); + gd.on('plotly_sliderchange', function() { cntChange++; }); + + function assertEventCounts(starts, moves, ends, changes) { + expect(cntStart).toEqual(starts); + expect(cntMove).toEqual(moves); + expect(cntEnd).toEqual(ends); + expect(cntChange).toEqual(changes); + } + + assertEventCounts(0, 0, 0, 0); + + var firstGroup = gd._fullLayout._infolayer.select('.' + constants.railTouchRectClass); + var railNode = firstGroup.node(); + var touchRect = railNode.getBoundingClientRect(); + + // Dispatch a click on the right side of the bar: + railNode.dispatchEvent(new MouseEvent('mousedown', { + clientY: touchRect.top + 5, + clientX: touchRect.left + touchRect.width - 5, + })); + + setTimeout(function() { + // One slider received a mousedown, two linked sliders have received a change: + assertEventCounts(1, 0, 0, 2); + + setTimeout(function() { + // Drag to the left side: + gd.dispatchEvent(new MouseEvent('mousemove', { + clientY: touchRect.top + 5, + clientX: touchRect.left + 5, + })); + + setTimeout(function() { + // On move, now two linked sliders have received two changes each: + assertEventCounts(1, 1, 0, 4); + + gd.dispatchEvent(new MouseEvent('mouseup')); + + // Now all have been receivd: + assertEventCounts(1, 1, 1, 4); + + done(); + }, 10); + }, 10); + }, 10); + }); + function assertNodeCount(query, cnt) { expect(d3.selectAll(query).size()).toEqual(cnt); } From 23d0e48b78bde0f9ec724853657e223bbcd5444f Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Wed, 9 Nov 2016 17:08:35 -0500 Subject: [PATCH 2/4] Rewrite slider events --- src/components/sliders/draw.js | 23 ++++------ test/jasmine/tests/sliders_test.js | 68 +++++++++++++++++------------- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/components/sliders/draw.js b/src/components/sliders/draw.js index 06bfd2ccbd5..3b7efda5f63 100644 --- a/src/components/sliders/draw.js +++ b/src/components/sliders/draw.js @@ -361,11 +361,7 @@ function handleInput(gd, sliderGroup, sliderOpts, normalizedPosition, doTransiti var quantizedPosition = Math.round(normalizedPosition * (sliderOpts.steps.length - 1)); if(quantizedPosition !== sliderOpts.active) { - var ret = {previousActive: sliderOpts.active}; - setActive(gd, sliderGroup, sliderOpts, quantizedPosition, true, doTransition); - - return ret; } } @@ -380,6 +376,7 @@ function setActive(gd, sliderGroup, sliderOpts, index, doCallback, doTransition) gd.emit('plotly_sliderchange', { slider: sliderOpts, + interaction: doCallback, previousActive: previousActive }); @@ -409,28 +406,21 @@ function attachGripEvents(item, gd, sliderGroup, sliderOpts) { var $gd = d3.select(gd); item.on('mousedown', function() { + gd.emit('plotly_sliderstart', {slider: sliderOpts}); + var grip = sliderGroup.select('.' + constants.gripRectClass); d3.event.stopPropagation(); d3.event.preventDefault(); grip.call(Color.fill, sliderOpts.activebgcolor); - gd.emit('plotly_sliderdragstart', {slider: sliderOpts}); - var normalizedPosition = positionToNormalizedValue(sliderOpts, d3.mouse(node)[0]); handleInput(gd, sliderGroup, sliderOpts, normalizedPosition, true); sliderOpts._dragging = true; $gd.on('mousemove', function() { var normalizedPosition = positionToNormalizedValue(sliderOpts, d3.mouse(node)[0]); - var changes = handleInput(gd, sliderGroup, sliderOpts, normalizedPosition, false); - - if(changes) { - gd.emit('plotly_sliderdragmove', { - slider: sliderOpts, - previousActive: changes.previousActive - }); - } + handleInput(gd, sliderGroup, sliderOpts, normalizedPosition, false); }); $gd.on('mouseup', function() { @@ -439,7 +429,10 @@ function attachGripEvents(item, gd, sliderGroup, sliderOpts) { $gd.on('mouseup', null); $gd.on('mousemove', null); - gd.emit('plotly_sliderdragend', {slider: sliderOpts}); + gd.emit('plotly_sliderend', { + slider: sliderOpts, + step: sliderOpts.steps[sliderOpts.active] + }); }); }); } diff --git a/test/jasmine/tests/sliders_test.js b/test/jasmine/tests/sliders_test.js index 65b99c4589a..0e7c8a0bbcb 100644 --- a/test/jasmine/tests/sliders_test.js +++ b/test/jasmine/tests/sliders_test.js @@ -321,20 +321,28 @@ describe('sliders interactions', function() { it('should issue events on interaction', function(done) { var cntStart = 0; - var cntMove = 0; + var cntInteraction = 0; + var cntNonInteraction = 0; var cntEnd = 0; - var cntChange = 0; - - gd.on('plotly_sliderdragstart', function() { cntStart++; }); - gd.on('plotly_sliderdragmove', function() { cntMove++; }); - gd.on('plotly_sliderdragend', function() { cntEnd++; }); - gd.on('plotly_sliderchange', function() { cntChange++; }); - - function assertEventCounts(starts, moves, ends, changes) { - expect(cntStart).toEqual(starts); - expect(cntMove).toEqual(moves); - expect(cntEnd).toEqual(ends); - expect(cntChange).toEqual(changes); + + gd.on('plotly_sliderstart', function() { + cntStart++; + }).on('plotly_sliderchange', function(datum) { + if(datum.interaction) { + cntInteraction++; + } else { + cntNonInteraction++; + } + }).on('plotly_sliderend', function() { + cntEnd++; + }); + + function assertEventCounts(starts, interactions, noninteractions, ends) { + expect( + [cntStart, cntInteraction, cntNonInteraction, cntEnd] + ).toEqual( + [starts, interactions, noninteractions, ends] + ); } assertEventCounts(0, 0, 0, 0); @@ -350,29 +358,29 @@ describe('sliders interactions', function() { })); setTimeout(function() { - // One slider received a mousedown, two linked sliders have received a change: - assertEventCounts(1, 0, 0, 2); + // One slider received a mousedown, one received an interaction, and one received a change: + assertEventCounts(1, 1, 1, 0); - setTimeout(function() { - // Drag to the left side: - gd.dispatchEvent(new MouseEvent('mousemove', { - clientY: touchRect.top + 5, - clientX: touchRect.left + 5, - })); + // Drag to the left side: + gd.dispatchEvent(new MouseEvent('mousemove', { + clientY: touchRect.top + 5, + clientX: touchRect.left + 5, + })); - setTimeout(function() { - // On move, now two linked sliders have received two changes each: - assertEventCounts(1, 1, 0, 4); + setTimeout(function() { + // On move, now to changes for the each slider, and no ends: + assertEventCounts(1, 2, 2, 0); - gd.dispatchEvent(new MouseEvent('mouseup')); + gd.dispatchEvent(new MouseEvent('mouseup')); - // Now all have been receivd: - assertEventCounts(1, 1, 1, 4); + setTimeout(function() { + // Now an end: + assertEventCounts(1, 2, 2, 1); done(); - }, 10); - }, 10); - }, 10); + }, 50); + }, 50); + }, 50); }); function assertNodeCount(query, cnt) { From 0904ee70a6015420a52a7d1585c8a6c23010b0e0 Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Wed, 9 Nov 2016 17:11:54 -0500 Subject: [PATCH 3/4] Add one extra data param to slider events --- src/components/sliders/draw.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/sliders/draw.js b/src/components/sliders/draw.js index 3b7efda5f63..6679dcb408f 100644 --- a/src/components/sliders/draw.js +++ b/src/components/sliders/draw.js @@ -376,6 +376,7 @@ function setActive(gd, sliderGroup, sliderOpts, index, doCallback, doTransition) gd.emit('plotly_sliderchange', { slider: sliderOpts, + step: sliderOpts.steps[sliderOpts.active], interaction: doCallback, previousActive: previousActive }); From 2adf3874a61a5cffa55ff7e5778979fe669012b4 Mon Sep 17 00:00:00 2001 From: Ricky Reusser Date: Wed, 9 Nov 2016 17:27:40 -0500 Subject: [PATCH 4/4] Run lint-fix --- src/plot_api/plot_api.js | 2 +- src/plots/cartesian/tick_label_defaults.js | 4 +- src/plots/geo/set_scale.js | 2 +- src/traces/contour/plot.js | 6 +- src/traces/surface/convert.js | 4 +- test/jasmine/tests/heatmap_test.js | 74 +++++++++++----------- test/jasmine/tests/lib_test.js | 6 +- 7 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index fa45556f741..1507ba5e1fa 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -2005,7 +2005,7 @@ function _relayout(gd, aobj) { */ else if(['hovermode', 'dragmode'].indexOf(ai) !== -1) flags.domodebar = true; else if(['hovermode', 'dragmode', 'height', - 'width', 'autosize'].indexOf(ai) === -1) { + 'width', 'autosize'].indexOf(ai) === -1) { flags.doplot = true; } diff --git a/src/plots/cartesian/tick_label_defaults.js b/src/plots/cartesian/tick_label_defaults.js index 148368cb6b4..0d1ebebab74 100644 --- a/src/plots/cartesian/tick_label_defaults.js +++ b/src/plots/cartesian/tick_label_defaults.js @@ -67,8 +67,8 @@ module.exports = function handleTickLabelDefaults(containerIn, containerOut, coe */ function getShowAttrDflt(containerIn) { var showAttrsAll = ['showexponent', - 'showtickprefix', - 'showticksuffix'], + 'showtickprefix', + 'showticksuffix'], showAttrs = showAttrsAll.filter(function(a) { return containerIn[a] !== undefined; }), diff --git a/src/plots/geo/set_scale.js b/src/plots/geo/set_scale.js index 70d7220eccf..45c437bb1fb 100644 --- a/src/plots/geo/set_scale.js +++ b/src/plots/geo/set_scale.js @@ -127,7 +127,7 @@ function makeRangeBox(lon0, lat0, lon1, lat1) { return { type: 'Polygon', coordinates: [ - [ [lon0, lat0], + [ [lon0, lat0], [lon0, lat1], [lon0 + dlon4, lat1], [lon0 + 2 * dlon4, lat1], diff --git a/src/traces/contour/plot.js b/src/traces/contour/plot.js index 21076c87139..15471d82eba 100644 --- a/src/traces/contour/plot.js +++ b/src/traces/contour/plot.js @@ -320,7 +320,7 @@ function makePath(pi, loc, edgeflag) { // even # of pts - average central two else { newpt = [(getpt(ptavg)[0] + getpt(ptavg + 1)[0]) / 2, - (getpt(ptavg)[1] + getpt(ptavg + 1)[1]) / 2]; + (getpt(ptavg)[1] + getpt(ptavg + 1)[1]) / 2]; } pts.splice(cnt2 + 1, cnt - cnt2 + 1, newpt); @@ -458,12 +458,12 @@ function getInterpPx(pi, loc, step) { if(step[1]) { var dx = (pi.level - zxy) / (pi.z[locy][locx + 1] - zxy); return [xa.c2p((1 - dx) * pi.x[locx] + dx * pi.x[locx + 1], true), - ya.c2p(pi.y[locy], true)]; + ya.c2p(pi.y[locy], true)]; } else { var dy = (pi.level - zxy) / (pi.z[locy + 1][locx] - zxy); return [xa.c2p(pi.x[locx], true), - ya.c2p((1 - dy) * pi.y[locy] + dy * pi.y[locy + 1], true)]; + ya.c2p((1 - dy) * pi.y[locy] + dy * pi.y[locy + 1], true)]; } } diff --git a/src/traces/surface/convert.js b/src/traces/surface/convert.js index ac87cf277b1..2b3fbbda9ee 100644 --- a/src/traces/surface/convert.js +++ b/src/traces/surface/convert.js @@ -151,8 +151,8 @@ function refine(coords) { var padImg = padField(coords[i]); var scaledImg = ndarray(new Float32Array(nsize), nshape); homography(scaledImg, padImg, [scaleF, 0, 0, - 0, scaleF, 0, - 0, 0, 1]); + 0, scaleF, 0, + 0, 0, 1]); coords[i] = scaledImg; } diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index b10652a6548..61ccf74f4bf 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -452,43 +452,43 @@ describe('heatmap plot', function() { argumentsWithPadding = getContextStub.fillRect.calls.allArgs().slice(getContextStub.fillRect.calls.allArgs().length - 9); expect(argumentsWithPadding).toEqual([ - [argumentsWithoutPadding[0][0], - argumentsWithoutPadding[0][1] + edgeYGap, - argumentsWithoutPadding[0][2] - edgeXGap, - argumentsWithoutPadding[0][3] - edgeYGap], - [argumentsWithoutPadding[1][0] + centerXGap, - argumentsWithoutPadding[1][1] + edgeYGap, - argumentsWithoutPadding[1][2] - edgeXGap, - argumentsWithoutPadding[1][3] - edgeYGap], - [argumentsWithoutPadding[2][0] + edgeXGap, - argumentsWithoutPadding[2][1] + edgeYGap, - argumentsWithoutPadding[2][2] - edgeXGap, - argumentsWithoutPadding[2][3] - edgeYGap], - [argumentsWithoutPadding[3][0], - argumentsWithoutPadding[3][1] + centerYGap, - argumentsWithoutPadding[3][2] - edgeXGap, - argumentsWithoutPadding[3][3] - edgeYGap], - [argumentsWithoutPadding[4][0] + centerXGap, - argumentsWithoutPadding[4][1] + centerYGap, - argumentsWithoutPadding[4][2] - edgeXGap, - argumentsWithoutPadding[4][3] - edgeYGap], - [argumentsWithoutPadding[5][0] + edgeXGap, - argumentsWithoutPadding[5][1] + centerYGap, - argumentsWithoutPadding[5][2] - edgeXGap, - argumentsWithoutPadding[5][3] - edgeYGap], - [argumentsWithoutPadding[6][0], - argumentsWithoutPadding[6][1], - argumentsWithoutPadding[6][2] - edgeXGap, - argumentsWithoutPadding[6][3] - edgeYGap], - [argumentsWithoutPadding[7][0] + centerXGap, - argumentsWithoutPadding[7][1], - argumentsWithoutPadding[7][2] - edgeXGap, - argumentsWithoutPadding[7][3] - edgeYGap], - [argumentsWithoutPadding[8][0] + edgeXGap, - argumentsWithoutPadding[8][1], - argumentsWithoutPadding[8][2] - edgeXGap, - argumentsWithoutPadding[8][3] - edgeYGap - ]]); + [argumentsWithoutPadding[0][0], + argumentsWithoutPadding[0][1] + edgeYGap, + argumentsWithoutPadding[0][2] - edgeXGap, + argumentsWithoutPadding[0][3] - edgeYGap], + [argumentsWithoutPadding[1][0] + centerXGap, + argumentsWithoutPadding[1][1] + edgeYGap, + argumentsWithoutPadding[1][2] - edgeXGap, + argumentsWithoutPadding[1][3] - edgeYGap], + [argumentsWithoutPadding[2][0] + edgeXGap, + argumentsWithoutPadding[2][1] + edgeYGap, + argumentsWithoutPadding[2][2] - edgeXGap, + argumentsWithoutPadding[2][3] - edgeYGap], + [argumentsWithoutPadding[3][0], + argumentsWithoutPadding[3][1] + centerYGap, + argumentsWithoutPadding[3][2] - edgeXGap, + argumentsWithoutPadding[3][3] - edgeYGap], + [argumentsWithoutPadding[4][0] + centerXGap, + argumentsWithoutPadding[4][1] + centerYGap, + argumentsWithoutPadding[4][2] - edgeXGap, + argumentsWithoutPadding[4][3] - edgeYGap], + [argumentsWithoutPadding[5][0] + edgeXGap, + argumentsWithoutPadding[5][1] + centerYGap, + argumentsWithoutPadding[5][2] - edgeXGap, + argumentsWithoutPadding[5][3] - edgeYGap], + [argumentsWithoutPadding[6][0], + argumentsWithoutPadding[6][1], + argumentsWithoutPadding[6][2] - edgeXGap, + argumentsWithoutPadding[6][3] - edgeYGap], + [argumentsWithoutPadding[7][0] + centerXGap, + argumentsWithoutPadding[7][1], + argumentsWithoutPadding[7][2] - edgeXGap, + argumentsWithoutPadding[7][3] - edgeYGap], + [argumentsWithoutPadding[8][0] + edgeXGap, + argumentsWithoutPadding[8][1], + argumentsWithoutPadding[8][2] - edgeXGap, + argumentsWithoutPadding[8][3] - edgeYGap + ]]); done(); }); }); diff --git a/test/jasmine/tests/lib_test.js b/test/jasmine/tests/lib_test.js index f57d5c2fc17..1cba4bd7745 100644 --- a/test/jasmine/tests/lib_test.js +++ b/test/jasmine/tests/lib_test.js @@ -695,7 +695,7 @@ describe('Test lib.js:', function() { var colVal = 'red', sizeVal = 14, attrs = {testMarker: {testColor: {valType: 'color', dflt: 'rgba(0, 0, 0, 0)'}, - testSize: {valType: 'number', dflt: 20}}}, + testSize: {valType: 'number', dflt: 20}}}, obj = {testMarker: {testColor: colVal, testSize: sizeVal}}, outObj = {}, colOut = coerce2(obj, outObj, attrs, 'testMarker.testColor'), @@ -711,7 +711,7 @@ describe('Test lib.js:', function() { var colVal = 'r', sizeVal = 'aaaaah!', attrs = {testMarker: {testColor: {valType: 'color', dflt: 'rgba(0, 0, 0, 0)'}, - testSize: {valType: 'number', dflt: 20}}}, + testSize: {valType: 'number', dflt: 20}}}, obj = {testMarker: {testColor: colVal, testSize: sizeVal}}, outObj = {}, colOut = coerce2(obj, outObj, attrs, 'testMarker.testColor'), @@ -727,7 +727,7 @@ describe('Test lib.js:', function() { var colVal = null, sizeVal = null, attrs = {testMarker: {testColor: {valType: 'color', dflt: 'rgba(0, 0, 0, 0)'}, - testSize: {valType: 'number', dflt: 20}}}, + testSize: {valType: 'number', dflt: 20}}}, obj = {testMarker: {testColor: colVal, testSize: sizeVal}}, outObj = {}, colOut = coerce2(obj, outObj, attrs, 'testMarker.testColor'),