diff --git a/demos/zoom-variations.html b/demos/zoom-variations.html
new file mode 100644
index 00000000..424de8a4
--- /dev/null
+++ b/demos/zoom-variations.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+ Zoom Variations
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dist/uPlot.esm.d.ts b/dist/uPlot.esm.d.ts
index e260c6d9..3ffd2f1a 100644
--- a/dist/uPlot.esm.d.ts
+++ b/dist/uPlot.esm.d.ts
@@ -233,6 +233,7 @@ declare namespace uPlot {
setScale?: boolean; // true
x?: boolean; // true
y?: boolean; // false
+ uni?: number; // null
};
/** sync cursor between multiple charts */
diff --git a/src/opts.js b/src/opts.js
index 13ecd2a8..62069c12 100644
--- a/src/opts.js
+++ b/src/opts.js
@@ -306,6 +306,7 @@ export const cursorOpts = {
setScale: true,
x: true,
y: false,
+ uni: null
},
focus: {
diff --git a/src/uPlot.js b/src/uPlot.js
index 70f3cc43..dbbd06e1 100644
--- a/src/uPlot.js
+++ b/src/uPlot.js
@@ -1611,18 +1611,51 @@ export default function uPlot(opts, data, then) {
// nit: cursor.drag.setSelect is assumed always true
if (mouseLeft1 >= 0 && select.show && dragging) {
// setSelect should not be triggered on move events
- if (drag.x) {
+
+ let dragX = drag.x;
+ let dragY = drag.y;
+ let uni = drag.uni;
+
+ if (uni != null) {
+ let xDistance = abs(mouseLeft0 - mouseLeft1);
+ let yDistance = abs(mouseTop0 - mouseTop1);
+
+ if (xDistance < uni)
+ dragX = false;
+ if (yDistance < uni)
+ dragY = false;
+
+ // neither x or y passed the threshold, we are in the magenta box (#219). In this
+ // scenario, we choose a unidirectional zoom based on which point is furthest from
+ // the origin M0
+ if (!dragX && !dragY) {
+ if (xDistance > yDistance)
+ dragX = true;
+ else
+ dragY = true;
+ }
+ }
+
+ if (dragX) {
let minX = min(mouseLeft0, mouseLeft1);
let maxX = max(mouseLeft0, mouseLeft1);
setStylePx(selectDiv, LEFT, select[LEFT] = minX);
setStylePx(selectDiv, WIDTH, select[WIDTH] = maxX - minX);
+ if (uni != null && !dragY) {
+ setStylePx(selectDiv, TOP, select[TOP] = 0);
+ setStylePx(selectDiv, HEIGHT, select[HEIGHT] = plotHgtCss);
+ }
}
- if (drag.y) {
+ if (dragY) {
let minY = min(mouseTop0, mouseTop1);
let maxY = max(mouseTop0, mouseTop1);
setStylePx(selectDiv, TOP, select[TOP] = minY);
setStylePx(selectDiv, HEIGHT, select[HEIGHT] = maxY - minY);
+ if (uni != null && !dragX) {
+ setStylePx(selectDiv, LEFT, select[LEFT] = 0);
+ setStylePx(selectDiv, WIDTH, select[WIDTH] = plotWidCss);
+ }
}
}