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); + } } }