From 14ae77cafa0069683cba00ee597e28814e1e2151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 28 Jun 2017 15:38:15 -0400 Subject: [PATCH 1/5] rename variable `plot` to more appropriate `zoomLayer` - a follow-up to https://github.com/plotly/plotly.js/pull/448/ --- src/plots/cartesian/select.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plots/cartesian/select.js b/src/plots/cartesian/select.js index cba5decac75..045585cdbac 100644 --- a/src/plots/cartesian/select.js +++ b/src/plots/cartesian/select.js @@ -23,7 +23,7 @@ var MINSELECT = constants.MINSELECT; function getAxId(ax) { return ax._id; } module.exports = function prepSelect(e, startX, startY, dragOptions, mode) { - var plot = dragOptions.gd._fullLayout._zoomlayer, + var zoomLayer = dragOptions.gd._fullLayout._zoomlayer, dragBBox = dragOptions.element.getBoundingClientRect(), xs = dragOptions.plotinfo.xaxis._offset, ys = dragOptions.plotinfo.yaxis._offset, @@ -43,7 +43,7 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) { pts = filteredPolygon([[x0, y0]], constants.BENDPX); } - var outlines = plot.selectAll('path.select-outline').data([1, 2]); + var outlines = zoomLayer.selectAll('path.select-outline').data([1, 2]); outlines.enter() .append('path') @@ -51,7 +51,7 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) { .attr('transform', 'translate(' + xs + ', ' + ys + ')') .attr('d', path0 + 'Z'); - var corners = plot.append('path') + var corners = zoomLayer.append('path') .attr('class', 'zoombox-corners') .style({ fill: color.background, From ec6e3608ef3d562f7145eec5ee25d5b368325ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 28 Jun 2017 15:39:54 -0400 Subject: [PATCH 2/5] rm ternary-only zoom layer - use graph-wide for ternary zoom effects, no need to another layer to accomplish this. --- src/plots/ternary/ternary.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plots/ternary/ternary.js b/src/plots/ternary/ternary.js index fa9fcbfcf67..920f4d8b2b0 100644 --- a/src/plots/ternary/ternary.js +++ b/src/plots/ternary/ternary.js @@ -88,7 +88,6 @@ proto.makeFramework = function() { 'backplot', 'grids', 'frontplot', - 'zoom', 'aaxis', 'baxis', 'caxis', 'axlines' ]; var toplevel = _this.plotContainer.selectAll('g.toplevel') @@ -263,7 +262,7 @@ proto.adjustLayout = function(ternaryLayout, graphSize) { _this.layers.plotbg.select('path').attr('d', triangleClip); var plotTransform = 'translate(' + x0 + ',' + y0 + ')'; - _this.plotContainer.selectAll('.scatterlayer,.maplayer,.zoom') + _this.plotContainer.selectAll('.scatterlayer,.maplayer') .attr('transform', plotTransform); // TODO: shift axes to accommodate linewidth*sin(30) tick mark angle @@ -382,7 +381,7 @@ proto.initInteractions = function() { var _this = this, dragger = _this.layers.plotbg.select('path').node(), gd = _this.graphDiv, - zoomContainer = _this.layers.zoom; + zoomContainer = gd._fullLayout._zoomlayer; // use plotbg for the main interactions var dragOptions = { @@ -441,6 +440,7 @@ proto.initInteractions = function() { zb = zoomContainer.append('path') .attr('class', 'zoombox') + .attr('transform', 'translate(' + _this.x0 + ', ' + _this.y0 + ')') .style({ 'fill': lum > 0.2 ? 'rgba(0,0,0,0)' : 'rgba(255,255,255,0)', 'stroke-width': 0 @@ -449,6 +449,7 @@ proto.initInteractions = function() { corners = zoomContainer.append('path') .attr('class', 'zoombox-corners') + .attr('transform', 'translate(' + _this.x0 + ', ' + _this.y0 + ')') .style({ fill: Color.background, stroke: Color.defaultLine, @@ -603,7 +604,7 @@ proto.initInteractions = function() { // until we get around to persistent selections, remove the outline // here. The selection itself will be removed when the plot redraws // at the end. - _this.plotContainer.selectAll('.select-outline').remove(); + zoomContainer.selectAll('.select-outline').remove(); } function doubleClick() { From e3a2c84e02f88b78bc280688dfabf430b52a22cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 28 Jun 2017 15:40:40 -0400 Subject: [PATCH 3/5] DRY up select_test.js --- test/jasmine/tests/select_test.js | 43 ++++++++++++------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/test/jasmine/tests/select_test.js b/test/jasmine/tests/select_test.js index 37cf778b940..fbbe13c7f6a 100644 --- a/test/jasmine/tests/select_test.js +++ b/test/jasmine/tests/select_test.js @@ -16,7 +16,7 @@ describe('select box and lasso', function() { var selectPath = [[93, 193], [143, 193]]; var lassoPath = [[316, 171], [318, 239], [335, 243], [328, 169]]; - beforeEach(function() { + beforeAll(function() { jasmine.addMatchers(customMatchers); }); @@ -59,6 +59,13 @@ describe('select box and lasso', function() { }); } + function assertSelectionNodes(cornerCnt, outlineCnt) { + expect(d3.selectAll('.zoomlayer > .zoombox-corners').size()) + .toBe(cornerCnt, 'selection corner count'); + expect(d3.selectAll('.zoomlayer > .select-outline').size()) + .toBe(outlineCnt, 'selection outline count'); + } + describe('select elements', function() { var mockCopy = Lib.extendDeep({}, mock); mockCopy.layout.dragmode = 'select'; @@ -80,30 +87,21 @@ describe('select box and lasso', function() { y2 = 50; gd.once('plotly_selecting', function() { - expect(d3.selectAll('.zoomlayer > .zoombox-corners').size()) - .toEqual(1); - expect(d3.selectAll('.zoomlayer > .select-outline').size()) - .toEqual(2); + assertSelectionNodes(1, 2); }); gd.once('plotly_selected', function() { - expect(d3.selectAll('.zoomlayer > .zoombox-corners').size()) - .toEqual(0); - expect(d3.selectAll('.zoomlayer > .select-outline').size()) - .toEqual(2); + assertSelectionNodes(0, 2); }); gd.once('plotly_deselect', function() { - expect(d3.selectAll('.zoomlayer > .select-outline').size()) - .toEqual(0); + assertSelectionNodes(0, 0); }); mouseEvent('mousemove', x0, y0); - expect(d3.selectAll('.zoomlayer > .zoombox-corners').size()) - .toEqual(0); + assertSelectionNodes(0, 0); drag([[x0, y0], [x1, y1]]); - doubleClick(x2, y2).then(done); }); }); @@ -129,30 +127,21 @@ describe('select box and lasso', function() { y2 = 50; gd.once('plotly_selecting', function() { - expect(d3.selectAll('.zoomlayer > .zoombox-corners').size()) - .toEqual(1); - expect(d3.selectAll('.zoomlayer > .select-outline').size()) - .toEqual(2); + assertSelectionNodes(1, 2); }); gd.once('plotly_selected', function() { - expect(d3.selectAll('.zoomlayer > .zoombox-corners').size()) - .toEqual(0); - expect(d3.selectAll('.zoomlayer > .select-outline').size()) - .toEqual(2); + assertSelectionNodes(0, 2); }); gd.once('plotly_deselect', function() { - expect(d3.selectAll('.zoomlayer > .select-outline').size()) - .toEqual(0); + assertSelectionNodes(0, 0); }); mouseEvent('mousemove', x0, y0); - expect(d3.selectAll('.zoomlayer > .zoombox-corners').size()) - .toEqual(0); + assertSelectionNodes(0, 0); drag([[x0, y0], [x1, y1]]); - doubleClick(x2, y2).then(done); }); }); From 4bbbe5cdc13ffc23b9214ba3621fa3924ff13cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 28 Jun 2017 15:41:31 -0400 Subject: [PATCH 4/5] fix select/lasso on ternary subplots - broken since https://github.com/plotly/plotly.js/pull/448 - :lock: down with test --- src/plots/ternary/index.js | 4 +++ src/plots/ternary/ternary.js | 13 +++++--- test/jasmine/tests/select_test.js | 52 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/plots/ternary/index.js b/src/plots/ternary/index.js index e1da80af7b1..2b24ed0938a 100644 --- a/src/plots/ternary/index.js +++ b/src/plots/ternary/index.js @@ -69,4 +69,8 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) oldTernary.clipDef.remove(); } } + + if(oldFullLayout._zoomlayer) { + oldFullLayout._zoomlayer.selectAll('.select-outline').remove(); + } }; diff --git a/src/plots/ternary/ternary.js b/src/plots/ternary/ternary.js index 920f4d8b2b0..4670167ca18 100644 --- a/src/plots/ternary/ternary.js +++ b/src/plots/ternary/ternary.js @@ -122,10 +122,6 @@ proto.makeFramework = function() { _this.plotContainer.selectAll('.backplot,.frontplot,.grids') .call(Drawing.setClipUrl, clipId); - - if(!_this.graphDiv._context.staticPlot) { - _this.initInteractions(); - } }; var w_over_h = Math.sqrt(4 / 3); @@ -302,6 +298,10 @@ proto.adjustLayout = function(ternaryLayout, graphSize) { 'M' + (x0 + w / 2) + ',' + y0 + 'l' + (w / 2) + ',' + h : 'M0,0') .call(Color.stroke, caxis.linecolor || '#000') .style('stroke-width', (caxis.linewidth || 0) + 'px'); + + if(!_this.graphDiv._context.staticPlot) { + _this.initInteractions(); + } }; proto.drawAxes = function(doTitles) { @@ -387,7 +387,10 @@ proto.initInteractions = function() { var dragOptions = { element: dragger, gd: gd, - plotinfo: {plot: zoomContainer}, + plotinfo: { + xaxis: _this.xaxis, + yaxis: _this.yaxis + }, doubleclick: doubleClick, subplot: _this.id, prepFn: function(e, startX, startY) { diff --git a/test/jasmine/tests/select_test.js b/test/jasmine/tests/select_test.js index fbbe13c7f6a..746fa779690 100644 --- a/test/jasmine/tests/select_test.js +++ b/test/jasmine/tests/select_test.js @@ -6,6 +6,7 @@ var doubleClick = require('../assets/double_click'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); +var fail = require('../assets/fail_test'); var mouseEvent = require('../assets/mouse_event'); var customMatchers = require('../assets/custom_matchers'); @@ -368,4 +369,55 @@ describe('select box and lasso', function() { }) .then(done); }); + + it('should work on scatterternary traces', function(done) { + var fig = Lib.extendDeep({}, require('@mocks/ternary_simple')); + var gd = createGraphDiv(); + var pts = []; + + fig.layout.width = 800; + fig.layout.dragmode = 'select'; + + function assertPoints(expected) { + expect(pts.length).toBe(expected.length, 'selected points length'); + + pts.forEach(function(p, i) { + var e = expected[i]; + expect(p.a).toBe(e.a, 'selected pt a val'); + expect(p.b).toBe(e.b, 'selected pt b val'); + expect(p.c).toBe(e.c, 'selected pt c val'); + }); + pts = []; + } + + Plotly.plot(gd, fig).then(function() { + gd.on('plotly_selected', function(data) { + pts = data.points; + }); + + assertSelectionNodes(0, 0); + drag([[400, 200], [445, 235]]); + assertSelectionNodes(0, 2); + assertPoints([{ a: 0.5, b: 0.25, c: 0.25 }]); + + return Plotly.relayout(gd, 'dragmode', 'lasso'); + }) + .then(function() { + assertSelectionNodes(0, 0); + drag([[400, 200], [445, 200], [445, 235], [400, 235], [400, 200]]); + assertSelectionNodes(0, 2); + assertPoints([{ a: 0.5, b: 0.25, c: 0.25 }]); + + // should work after a relayout too + return Plotly.relayout(gd, 'width', 400); + }) + .then(function() { + assertSelectionNodes(0, 0); + drag([[200, 200], [230, 200], [230, 230], [200, 230], [200, 200]]); + assertSelectionNodes(0, 2); + assertPoints([{ a: 0.5, b: 0.25, c: 0.25 }]); + }) + .catch(fail) + .then(done); + }); }); From 5a48568850ccf0dc119c7bbd3de0a7719bcdf404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 28 Jun 2017 15:41:54 -0400 Subject: [PATCH 5/5] add select/lasso for scattercarpet traces --- test/jasmine/tests/select_test.js | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/jasmine/tests/select_test.js b/test/jasmine/tests/select_test.js index 746fa779690..86d0825700c 100644 --- a/test/jasmine/tests/select_test.js +++ b/test/jasmine/tests/select_test.js @@ -420,4 +420,44 @@ describe('select box and lasso', function() { .catch(fail) .then(done); }); + + it('should work on scattercarpet traces', function(done) { + var fig = Lib.extendDeep({}, require('@mocks/scattercarpet')); + var gd = createGraphDiv(); + var pts = []; + + fig.layout.dragmode = 'select'; + + function assertPoints(expected) { + expect(pts.length).toBe(expected.length, 'selected points length'); + + pts.forEach(function(p, i) { + var e = expected[i]; + expect(p.a).toBe(e.a, 'selected pt a val'); + expect(p.b).toBe(e.b, 'selected pt b val'); + }); + pts = []; + } + + Plotly.plot(gd, fig).then(function() { + gd.on('plotly_selected', function(data) { + pts = data.points; + }); + + assertSelectionNodes(0, 0); + drag([[300, 200], [400, 250]]); + assertSelectionNodes(0, 2); + assertPoints([{ a: 0.2, b: 1.5 }]); + + return Plotly.relayout(gd, 'dragmode', 'lasso'); + }) + .then(function() { + assertSelectionNodes(0, 0); + drag([[300, 200], [400, 200], [400, 250], [300, 250], [300, 200]]); + assertSelectionNodes(0, 2); + assertPoints([{ a: 0.2, b: 1.5 }]); + }) + .catch(fail) + .then(done); + }); });