Skip to content

Commit 2afdb22

Browse files
committed
add autoscaling for y-axis
1 parent 2656167 commit 2afdb22

File tree

6 files changed

+645
-1
lines changed

6 files changed

+645
-1
lines changed

src/plot_api/plot_api.js

+1
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ function setPlotContext(gd, config) {
472472
context.showTips = false;
473473
context.showLink = false;
474474
context.displayModeBar = false;
475+
context.autoscaleYAxis = false;
475476
}
476477

477478
// make sure hover-only devices have mode bar visible

src/plot_api/plot_config.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,8 @@ module.exports = {
126126

127127
// Set global transform to be applied to all traces with no
128128
// specification needed
129-
globalTransforms: []
129+
globalTransforms: [],
130+
131+
// auto scale Y axis depending on the data on the screen
132+
autoscaleYAxis: false
130133
};

src/plots/cartesian/dragbox.js

+75
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var Drawing = require('../../components/drawing');
2121
var setCursor = require('../../lib/setcursor');
2222
var dragElement = require('../../components/dragelement');
2323
var FROM_TL = require('../../constants/alignment').FROM_TL;
24+
var Axes = require('../../plots/cartesian/axes');
2425

2526
var Plots = require('../plots');
2627

@@ -363,6 +364,11 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
363364
return Lib.pauseEvent(e);
364365
}
365366

367+
// If autoscaleYAxis, then disable y axis scale:
368+
if(gd._context.autoscaleYAxis) {
369+
ns = '';
370+
}
371+
366372
var pc = gd.querySelector('.plotly');
367373

368374
recomputeAxisLists();
@@ -662,6 +668,11 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
662668
// ticksAndAnnotations again - it's unnecessary and would overwrite `updates`
663669
updateSubplots([0, 0, pw, ph]);
664670

671+
// change Y axis range and overwrite 'updates'
672+
if(gd._context.autoscaleYAxis) {
673+
autoscaleYAxis();
674+
}
675+
665676
// since we may have been redrawing some things during the drag, we may have
666677
// accumulated MathJax promises - wait for them before we relayout.
667678
Lib.syncOrAsync([
@@ -770,6 +781,70 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
770781
}
771782
}
772783

784+
// Find new range for y axis according new x axis range
785+
function autoscaleYAxis() {
786+
var plotinfos = fullLayout._plots;
787+
var subplots = Object.keys(plotinfos);
788+
var i;
789+
for(i = 0; i < subplots.length; i++) {
790+
var subplot = plotinfos[subplots[i]];
791+
var ya = subplot.yaxis;
792+
var xa = subplot.xaxis;
793+
var xRange = [updates[xa._name + '.range[0]'], updates[xa._name + '.range[1]']];
794+
var fitData = [];
795+
var traces = subplot.plot.selectAll('.trace');
796+
var newRange;
797+
798+
traces.call(processTraces, subplot, xRange, fitData);
799+
800+
if(fitData.length) {
801+
ya._min = [];
802+
ya._max = [];
803+
ya.autorange = true;
804+
Axes.expand(ya, fitData, {padded: true});
805+
newRange = Axes.getAutoRange(ya);
806+
updates[ya._name + '.range[0]'] = newRange[0];
807+
updates[ya._name + '.range[1]'] = newRange[1];
808+
809+
// Do not change y range if only one point is on the screen
810+
if(fitData.length === 1) {
811+
updates[ya._name + '.range[0]'] = ya.range[0];
812+
updates[ya._name + '.range[1]'] = ya.range[1];
813+
}
814+
}
815+
}
816+
}
817+
818+
function processTraces(traces, subplot, newRange, result) {
819+
traces.each(function(d) {
820+
getDataInRange(d, subplot, newRange, result);
821+
});
822+
}
823+
824+
// Find data points within the x axis range to build y range
825+
function getDataInRange(data, subplot, newRange, result) {
826+
var xa = subplot.xaxis;
827+
828+
data.forEach(function(d) {
829+
isPtWithinRange(xa, d, newRange) ? result.push(d.y) : null;
830+
});
831+
}
832+
833+
function isPtWithinRange(ax, d, newRange) {
834+
var data = d.x;
835+
var reversed = newRange[0] > newRange[1];
836+
837+
if(ax.type === 'date') {
838+
data = ax.l2d(data);
839+
} else if(ax.type === 'log') {
840+
data = ax.c2r(data);
841+
}
842+
843+
return reversed ?
844+
data >= newRange[1] && data <= newRange[0] :
845+
data >= newRange[0] && data <= newRange[1];
846+
}
847+
773848
return dragger;
774849
};
775850

34.1 KB
Loading

0 commit comments

Comments
 (0)