diff --git a/src/plot_api/plot_config.js b/src/plot_api/plot_config.js index d54dd1a05a6..71871dad6be 100644 --- a/src/plot_api/plot_config.js +++ b/src/plot_api/plot_config.js @@ -48,6 +48,12 @@ module.exports = { // new users see some hints about interactivity showTips: true, + // enable axis pan/zoom drag handles + showAxisDragHandles: true, + + // enable direct range entry at the pan/zoom drag points (drag handles must be enabled above) + showAxisRangeEntryBoxes: true, + // link to open this plot in plotly showLink: false, diff --git a/src/plots/cartesian/dragbox.js b/src/plots/cartesian/dragbox.js index 22a253f287e..dd46b9037be 100644 --- a/src/plots/cartesian/dragbox.js +++ b/src/plots/cartesian/dragbox.js @@ -353,21 +353,23 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) { } else if(ew === 'e') hAlign = 'right'; - dragger3 - .call(svgTextUtils.makeEditable, null, { - immediate: true, - background: fullLayout.paper_bgcolor, - text: String(initialText), - fill: ax.tickfont ? ax.tickfont.color : '#444', - horizontalAlign: hAlign, - verticalAlign: vAlign - }) - .on('edit', function(text) { - var v = ax.d2r(text); - if(v !== undefined) { - Plotly.relayout(gd, attrStr, v); - } - }); + if(gd._context.showAxisRangeEntryBoxes) { + dragger3 + .call(svgTextUtils.makeEditable, null, { + immediate: true, + background: fullLayout.paper_bgcolor, + text: String(initialText), + fill: ax.tickfont ? ax.tickfont.color : '#444', + horizontalAlign: hAlign, + verticalAlign: vAlign + }) + .on('edit', function(text) { + var v = ax.d2r(text); + if(v !== undefined) { + Plotly.relayout(gd, attrStr, v); + } + }); + } } } diff --git a/src/plots/cartesian/graph_interact.js b/src/plots/cartesian/graph_interact.js index 835873e5e39..6075ebd66d0 100644 --- a/src/plots/cartesian/graph_interact.js +++ b/src/plots/cartesian/graph_interact.js @@ -153,36 +153,39 @@ fx.init = function(gd) { }; // corner draggers - dragBox(gd, plotinfo, -DRAGGERSIZE, -DRAGGERSIZE, - DRAGGERSIZE, DRAGGERSIZE, 'n', 'w'); - dragBox(gd, plotinfo, xa._length, -DRAGGERSIZE, - DRAGGERSIZE, DRAGGERSIZE, 'n', 'e'); - dragBox(gd, plotinfo, -DRAGGERSIZE, ya._length, - DRAGGERSIZE, DRAGGERSIZE, 's', 'w'); - dragBox(gd, plotinfo, xa._length, ya._length, - DRAGGERSIZE, DRAGGERSIZE, 's', 'e'); - } - - // x axis draggers - if you have overlaid plots, - // these drag each axis separately - if(isNumeric(y0)) { - if(xa.anchor === 'free') y0 -= fullLayout._size.h * (1 - ya.domain[1]); - dragBox(gd, plotinfo, xa._length * 0.1, y0, - xa._length * 0.8, DRAGGERSIZE, '', 'ew'); - dragBox(gd, plotinfo, 0, y0, - xa._length * 0.1, DRAGGERSIZE, '', 'w'); - dragBox(gd, plotinfo, xa._length * 0.9, y0, - xa._length * 0.1, DRAGGERSIZE, '', 'e'); + if(gd._context.showAxisDragHandles) { + dragBox(gd, plotinfo, -DRAGGERSIZE, -DRAGGERSIZE, + DRAGGERSIZE, DRAGGERSIZE, 'n', 'w'); + dragBox(gd, plotinfo, xa._length, -DRAGGERSIZE, + DRAGGERSIZE, DRAGGERSIZE, 'n', 'e'); + dragBox(gd, plotinfo, -DRAGGERSIZE, ya._length, + DRAGGERSIZE, DRAGGERSIZE, 's', 'w'); + dragBox(gd, plotinfo, xa._length, ya._length, + DRAGGERSIZE, DRAGGERSIZE, 's', 'e'); + } } - // y axis draggers - if(isNumeric(x0)) { - if(ya.anchor === 'free') x0 -= fullLayout._size.w * xa.domain[0]; - dragBox(gd, plotinfo, x0, ya._length * 0.1, - DRAGGERSIZE, ya._length * 0.8, 'ns', ''); - dragBox(gd, plotinfo, x0, ya._length * 0.9, - DRAGGERSIZE, ya._length * 0.1, 's', ''); - dragBox(gd, plotinfo, x0, 0, - DRAGGERSIZE, ya._length * 0.1, 'n', ''); + if(gd._context.showAxisDragHandles) { + // x axis draggers - if you have overlaid plots, + // these drag each axis separately + if(isNumeric(y0)) { + if(xa.anchor === 'free') y0 -= fullLayout._size.h * (1 - ya.domain[1]); + dragBox(gd, plotinfo, xa._length * 0.1, y0, + xa._length * 0.8, DRAGGERSIZE, '', 'ew'); + dragBox(gd, plotinfo, 0, y0, + xa._length * 0.1, DRAGGERSIZE, '', 'w'); + dragBox(gd, plotinfo, xa._length * 0.9, y0, + xa._length * 0.1, DRAGGERSIZE, '', 'e'); + } + // y axis draggers + if(isNumeric(x0)) { + if(ya.anchor === 'free') x0 -= fullLayout._size.w * xa.domain[0]; + dragBox(gd, plotinfo, x0, ya._length * 0.1, + DRAGGERSIZE, ya._length * 0.8, 'ns', ''); + dragBox(gd, plotinfo, x0, ya._length * 0.9, + DRAGGERSIZE, ya._length * 0.1, 's', ''); + dragBox(gd, plotinfo, x0, 0, + DRAGGERSIZE, ya._length * 0.1, 'n', ''); + } } }); diff --git a/test/jasmine/tests/config_test.js b/test/jasmine/tests/config_test.js index f066d4a1f07..9181e56d4e5 100644 --- a/test/jasmine/tests/config_test.js +++ b/test/jasmine/tests/config_test.js @@ -1,7 +1,9 @@ var Plotly = require('@lib/index'); var Plots = Plotly.Plots; +var Lib = require('@src/lib'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); +var click = require('../assets/click'); var mouseEvent = require('../assets/mouse_event'); describe('config argument', function() { @@ -269,4 +271,119 @@ describe('config argument', function() { }); }); + + describe('axis drag handles attribute', function() { + var mock = require('@mocks/14.json'); + + var gd; + var mockCopy; + + beforeEach(function(done) { + gd = createGraphDiv(); + mockCopy = Lib.extendDeep({}, mock); + done(); + }); + + afterEach(destroyGraphDiv); + + it('should have drag rectangles cursors by default', function() { + Plotly.plot(gd, mockCopy.data, {}); + + var nwdrag = document.getElementsByClassName('drag nwdrag'); + expect(nwdrag.length).toBe(1); + var nedrag = document.getElementsByClassName('drag nedrag'); + expect(nedrag.length).toBe(1); + var swdrag = document.getElementsByClassName('drag swdrag'); + expect(swdrag.length).toBe(1); + var sedrag = document.getElementsByClassName('drag sedrag'); + expect(sedrag.length).toBe(1); + var ewdrag = document.getElementsByClassName('drag ewdrag'); + expect(ewdrag.length).toBe(1); + var wdrag = document.getElementsByClassName('drag wdrag'); + expect(wdrag.length).toBe(1); + var edrag = document.getElementsByClassName('drag edrag'); + expect(edrag.length).toBe(1); + var nsdrag = document.getElementsByClassName('drag nsdrag'); + expect(nsdrag.length).toBe(1); + var sdrag = document.getElementsByClassName('drag sdrag'); + expect(sdrag.length).toBe(1); + var ndrag = document.getElementsByClassName('drag ndrag'); + expect(ndrag.length).toBe(1); + + }); + + it('should not have drag rectangles when disabled', function() { + Plotly.plot(gd, mockCopy.data, {}, { showAxisDragHandles: false }); + + var nwdrag = document.getElementsByClassName('drag nwdrag'); + expect(nwdrag.length).toBe(0); + var nedrag = document.getElementsByClassName('drag nedrag'); + expect(nedrag.length).toBe(0); + var swdrag = document.getElementsByClassName('drag swdrag'); + expect(swdrag.length).toBe(0); + var sedrag = document.getElementsByClassName('drag sedrag'); + expect(sedrag.length).toBe(0); + var ewdrag = document.getElementsByClassName('drag ewdrag'); + expect(ewdrag.length).toBe(0); + var wdrag = document.getElementsByClassName('drag wdrag'); + expect(wdrag.length).toBe(0); + var edrag = document.getElementsByClassName('drag edrag'); + expect(edrag.length).toBe(0); + var nsdrag = document.getElementsByClassName('drag nsdrag'); + expect(nsdrag.length).toBe(0); + var sdrag = document.getElementsByClassName('drag sdrag'); + expect(sdrag.length).toBe(0); + var ndrag = document.getElementsByClassName('drag ndrag'); + expect(ndrag.length).toBe(0); + }); + + }); + + describe('axis range entry attribute', function() { + var mock = require('@mocks/14.json'); + + var gd; + var mockCopy; + + beforeEach(function(done) { + gd = createGraphDiv(); + mockCopy = Lib.extendDeep({}, mock); + done(); + }); + + afterEach(destroyGraphDiv); + + it('show allow axis range entry by default', function() { + Plotly.plot(gd, mockCopy.data, {}); + + var corner = document.getElementsByClassName('edrag')[0]; + + var cornerBox = corner.getBoundingClientRect(), + cornerX = cornerBox.left + cornerBox.width / 2, + cornerY = cornerBox.top + cornerBox.height / 2; + + click(cornerX, cornerY); + + var editBox = document.getElementsByClassName('plugin-editable editable')[0]; + expect(editBox).toBeDefined(); + expect(editBox.getAttribute('contenteditable')).toBe('true'); + }); + + it('show not allow axis range entry when', function() { + Plotly.plot(gd, mockCopy.data, {}, { showAxisRangeEntryBoxes: false }); + + var corner = document.getElementsByClassName('edrag')[0]; + + var cornerBox = corner.getBoundingClientRect(), + cornerX = cornerBox.left + cornerBox.width / 2, + cornerY = cornerBox.top + cornerBox.height / 2; + + click(cornerX, cornerY); + + var editBox = document.getElementsByClassName('plugin-editable editable')[0]; + expect(editBox).toBeUndefined(); + }); + + + }); });