Skip to content

Commit 9ebefd7

Browse files
authored
Merge pull request #1389 from rpaskowitz/control_range_entry
Allow controlling pan/zoom range entry.
2 parents 85ca2b2 + 89605c5 commit 9ebefd7

File tree

4 files changed

+172
-44
lines changed

4 files changed

+172
-44
lines changed

src/plot_api/plot_config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ module.exports = {
4848
// new users see some hints about interactivity
4949
showTips: true,
5050

51+
// enable axis pan/zoom drag handles
52+
showAxisDragHandles: true,
53+
54+
// enable direct range entry at the pan/zoom drag points (drag handles must be enabled above)
55+
showAxisRangeEntryBoxes: true,
56+
5157
// link to open this plot in plotly
5258
showLink: false,
5359

src/plots/cartesian/dragbox.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -353,21 +353,23 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
353353
}
354354
else if(ew === 'e') hAlign = 'right';
355355

356-
dragger3
357-
.call(svgTextUtils.makeEditable, null, {
358-
immediate: true,
359-
background: fullLayout.paper_bgcolor,
360-
text: String(initialText),
361-
fill: ax.tickfont ? ax.tickfont.color : '#444',
362-
horizontalAlign: hAlign,
363-
verticalAlign: vAlign
364-
})
365-
.on('edit', function(text) {
366-
var v = ax.d2r(text);
367-
if(v !== undefined) {
368-
Plotly.relayout(gd, attrStr, v);
369-
}
370-
});
356+
if(gd._context.showAxisRangeEntryBoxes) {
357+
dragger3
358+
.call(svgTextUtils.makeEditable, null, {
359+
immediate: true,
360+
background: fullLayout.paper_bgcolor,
361+
text: String(initialText),
362+
fill: ax.tickfont ? ax.tickfont.color : '#444',
363+
horizontalAlign: hAlign,
364+
verticalAlign: vAlign
365+
})
366+
.on('edit', function(text) {
367+
var v = ax.d2r(text);
368+
if(v !== undefined) {
369+
Plotly.relayout(gd, attrStr, v);
370+
}
371+
});
372+
}
371373
}
372374
}
373375

src/plots/cartesian/graph_interact.js

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -153,36 +153,39 @@ fx.init = function(gd) {
153153
};
154154

155155
// corner draggers
156-
dragBox(gd, plotinfo, -DRAGGERSIZE, -DRAGGERSIZE,
157-
DRAGGERSIZE, DRAGGERSIZE, 'n', 'w');
158-
dragBox(gd, plotinfo, xa._length, -DRAGGERSIZE,
159-
DRAGGERSIZE, DRAGGERSIZE, 'n', 'e');
160-
dragBox(gd, plotinfo, -DRAGGERSIZE, ya._length,
161-
DRAGGERSIZE, DRAGGERSIZE, 's', 'w');
162-
dragBox(gd, plotinfo, xa._length, ya._length,
163-
DRAGGERSIZE, DRAGGERSIZE, 's', 'e');
164-
}
165-
166-
// x axis draggers - if you have overlaid plots,
167-
// these drag each axis separately
168-
if(isNumeric(y0)) {
169-
if(xa.anchor === 'free') y0 -= fullLayout._size.h * (1 - ya.domain[1]);
170-
dragBox(gd, plotinfo, xa._length * 0.1, y0,
171-
xa._length * 0.8, DRAGGERSIZE, '', 'ew');
172-
dragBox(gd, plotinfo, 0, y0,
173-
xa._length * 0.1, DRAGGERSIZE, '', 'w');
174-
dragBox(gd, plotinfo, xa._length * 0.9, y0,
175-
xa._length * 0.1, DRAGGERSIZE, '', 'e');
156+
if(gd._context.showAxisDragHandles) {
157+
dragBox(gd, plotinfo, -DRAGGERSIZE, -DRAGGERSIZE,
158+
DRAGGERSIZE, DRAGGERSIZE, 'n', 'w');
159+
dragBox(gd, plotinfo, xa._length, -DRAGGERSIZE,
160+
DRAGGERSIZE, DRAGGERSIZE, 'n', 'e');
161+
dragBox(gd, plotinfo, -DRAGGERSIZE, ya._length,
162+
DRAGGERSIZE, DRAGGERSIZE, 's', 'w');
163+
dragBox(gd, plotinfo, xa._length, ya._length,
164+
DRAGGERSIZE, DRAGGERSIZE, 's', 'e');
165+
}
176166
}
177-
// y axis draggers
178-
if(isNumeric(x0)) {
179-
if(ya.anchor === 'free') x0 -= fullLayout._size.w * xa.domain[0];
180-
dragBox(gd, plotinfo, x0, ya._length * 0.1,
181-
DRAGGERSIZE, ya._length * 0.8, 'ns', '');
182-
dragBox(gd, plotinfo, x0, ya._length * 0.9,
183-
DRAGGERSIZE, ya._length * 0.1, 's', '');
184-
dragBox(gd, plotinfo, x0, 0,
185-
DRAGGERSIZE, ya._length * 0.1, 'n', '');
167+
if(gd._context.showAxisDragHandles) {
168+
// x axis draggers - if you have overlaid plots,
169+
// these drag each axis separately
170+
if(isNumeric(y0)) {
171+
if(xa.anchor === 'free') y0 -= fullLayout._size.h * (1 - ya.domain[1]);
172+
dragBox(gd, plotinfo, xa._length * 0.1, y0,
173+
xa._length * 0.8, DRAGGERSIZE, '', 'ew');
174+
dragBox(gd, plotinfo, 0, y0,
175+
xa._length * 0.1, DRAGGERSIZE, '', 'w');
176+
dragBox(gd, plotinfo, xa._length * 0.9, y0,
177+
xa._length * 0.1, DRAGGERSIZE, '', 'e');
178+
}
179+
// y axis draggers
180+
if(isNumeric(x0)) {
181+
if(ya.anchor === 'free') x0 -= fullLayout._size.w * xa.domain[0];
182+
dragBox(gd, plotinfo, x0, ya._length * 0.1,
183+
DRAGGERSIZE, ya._length * 0.8, 'ns', '');
184+
dragBox(gd, plotinfo, x0, ya._length * 0.9,
185+
DRAGGERSIZE, ya._length * 0.1, 's', '');
186+
dragBox(gd, plotinfo, x0, 0,
187+
DRAGGERSIZE, ya._length * 0.1, 'n', '');
188+
}
186189
}
187190
});
188191

test/jasmine/tests/config_test.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
var Plotly = require('@lib/index');
22
var Plots = Plotly.Plots;
3+
var Lib = require('@src/lib');
34
var createGraphDiv = require('../assets/create_graph_div');
45
var destroyGraphDiv = require('../assets/destroy_graph_div');
6+
var click = require('../assets/click');
57
var mouseEvent = require('../assets/mouse_event');
68

79
describe('config argument', function() {
@@ -269,4 +271,119 @@ describe('config argument', function() {
269271
});
270272

271273
});
274+
275+
describe('axis drag handles attribute', function() {
276+
var mock = require('@mocks/14.json');
277+
278+
var gd;
279+
var mockCopy;
280+
281+
beforeEach(function(done) {
282+
gd = createGraphDiv();
283+
mockCopy = Lib.extendDeep({}, mock);
284+
done();
285+
});
286+
287+
afterEach(destroyGraphDiv);
288+
289+
it('should have drag rectangles cursors by default', function() {
290+
Plotly.plot(gd, mockCopy.data, {});
291+
292+
var nwdrag = document.getElementsByClassName('drag nwdrag');
293+
expect(nwdrag.length).toBe(1);
294+
var nedrag = document.getElementsByClassName('drag nedrag');
295+
expect(nedrag.length).toBe(1);
296+
var swdrag = document.getElementsByClassName('drag swdrag');
297+
expect(swdrag.length).toBe(1);
298+
var sedrag = document.getElementsByClassName('drag sedrag');
299+
expect(sedrag.length).toBe(1);
300+
var ewdrag = document.getElementsByClassName('drag ewdrag');
301+
expect(ewdrag.length).toBe(1);
302+
var wdrag = document.getElementsByClassName('drag wdrag');
303+
expect(wdrag.length).toBe(1);
304+
var edrag = document.getElementsByClassName('drag edrag');
305+
expect(edrag.length).toBe(1);
306+
var nsdrag = document.getElementsByClassName('drag nsdrag');
307+
expect(nsdrag.length).toBe(1);
308+
var sdrag = document.getElementsByClassName('drag sdrag');
309+
expect(sdrag.length).toBe(1);
310+
var ndrag = document.getElementsByClassName('drag ndrag');
311+
expect(ndrag.length).toBe(1);
312+
313+
});
314+
315+
it('should not have drag rectangles when disabled', function() {
316+
Plotly.plot(gd, mockCopy.data, {}, { showAxisDragHandles: false });
317+
318+
var nwdrag = document.getElementsByClassName('drag nwdrag');
319+
expect(nwdrag.length).toBe(0);
320+
var nedrag = document.getElementsByClassName('drag nedrag');
321+
expect(nedrag.length).toBe(0);
322+
var swdrag = document.getElementsByClassName('drag swdrag');
323+
expect(swdrag.length).toBe(0);
324+
var sedrag = document.getElementsByClassName('drag sedrag');
325+
expect(sedrag.length).toBe(0);
326+
var ewdrag = document.getElementsByClassName('drag ewdrag');
327+
expect(ewdrag.length).toBe(0);
328+
var wdrag = document.getElementsByClassName('drag wdrag');
329+
expect(wdrag.length).toBe(0);
330+
var edrag = document.getElementsByClassName('drag edrag');
331+
expect(edrag.length).toBe(0);
332+
var nsdrag = document.getElementsByClassName('drag nsdrag');
333+
expect(nsdrag.length).toBe(0);
334+
var sdrag = document.getElementsByClassName('drag sdrag');
335+
expect(sdrag.length).toBe(0);
336+
var ndrag = document.getElementsByClassName('drag ndrag');
337+
expect(ndrag.length).toBe(0);
338+
});
339+
340+
});
341+
342+
describe('axis range entry attribute', function() {
343+
var mock = require('@mocks/14.json');
344+
345+
var gd;
346+
var mockCopy;
347+
348+
beforeEach(function(done) {
349+
gd = createGraphDiv();
350+
mockCopy = Lib.extendDeep({}, mock);
351+
done();
352+
});
353+
354+
afterEach(destroyGraphDiv);
355+
356+
it('show allow axis range entry by default', function() {
357+
Plotly.plot(gd, mockCopy.data, {});
358+
359+
var corner = document.getElementsByClassName('edrag')[0];
360+
361+
var cornerBox = corner.getBoundingClientRect(),
362+
cornerX = cornerBox.left + cornerBox.width / 2,
363+
cornerY = cornerBox.top + cornerBox.height / 2;
364+
365+
click(cornerX, cornerY);
366+
367+
var editBox = document.getElementsByClassName('plugin-editable editable')[0];
368+
expect(editBox).toBeDefined();
369+
expect(editBox.getAttribute('contenteditable')).toBe('true');
370+
});
371+
372+
it('show not allow axis range entry when', function() {
373+
Plotly.plot(gd, mockCopy.data, {}, { showAxisRangeEntryBoxes: false });
374+
375+
var corner = document.getElementsByClassName('edrag')[0];
376+
377+
var cornerBox = corner.getBoundingClientRect(),
378+
cornerX = cornerBox.left + cornerBox.width / 2,
379+
cornerY = cornerBox.top + cornerBox.height / 2;
380+
381+
click(cornerX, cornerY);
382+
383+
var editBox = document.getElementsByClassName('plugin-editable editable')[0];
384+
expect(editBox).toBeUndefined();
385+
});
386+
387+
388+
});
272389
});

0 commit comments

Comments
 (0)