Skip to content

Commit b9b1398

Browse files
author
=
committed
adaptive unidirectional drag-zoom. close #219.
1 parent abacd02 commit b9b1398

File tree

4 files changed

+98
-2
lines changed

4 files changed

+98
-2
lines changed

demos/zoom-variations.html

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!doctype html>
2+
<html>
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<title>Zoom Variations</title>
7+
<meta name="viewport" content="width=device-width, initial-scale=1">
8+
9+
<link rel="stylesheet" href="../dist/uPlot.min.css">
10+
<style>
11+
.uplot {
12+
display: inline-block;
13+
width: 400px;
14+
}
15+
</style>
16+
</head>
17+
18+
<body>
19+
<script src="../dist/uPlot.iife.js"></script>
20+
<script>
21+
let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30];
22+
let vals = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
23+
24+
let data = [
25+
xs,
26+
xs.map((t, i) => vals[Math.floor(Math.random() * vals.length)])
27+
];
28+
29+
const opts = (title, dragOpts) => ({
30+
title: title,
31+
width: 400,
32+
height: 200,
33+
scales: {
34+
x: {
35+
time: false,
36+
},
37+
},
38+
cursor: {
39+
drag: dragOpts
40+
},
41+
series: [
42+
{},
43+
{
44+
stroke: "purple"
45+
}
46+
],
47+
});
48+
49+
let variations = [
50+
['X only', { x: true, y: false }],
51+
['Y only', { x: false, y: true }],
52+
['X or Y (adaptive)', { x: true, y: true, uni: Infinity }],
53+
['X or Y (omni)', { x: true, y: true }],
54+
['X or Y (adaptive + omni)', { x: true, y: true, uni: 20 }],
55+
];
56+
57+
variations.forEach((variation) => new uPlot(opts(...variation), data, document.body));
58+
</script>
59+
</body>
60+
61+
</html>

dist/uPlot.esm.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ declare namespace uPlot {
233233
setScale?: boolean; // true
234234
x?: boolean; // true
235235
y?: boolean; // false
236+
uni?: number; // null
236237
};
237238

238239
/** sync cursor between multiple charts */

src/opts.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ export const cursorOpts = {
306306
setScale: true,
307307
x: true,
308308
y: false,
309+
uni: null
309310
},
310311

311312
focus: {

src/uPlot.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,18 +1611,51 @@ export default function uPlot(opts, data, then) {
16111611
// nit: cursor.drag.setSelect is assumed always true
16121612
if (mouseLeft1 >= 0 && select.show && dragging) {
16131613
// setSelect should not be triggered on move events
1614-
if (drag.x) {
1614+
1615+
let dragX = drag.x;
1616+
let dragY = drag.y;
1617+
let uni = drag.uni;
1618+
1619+
if (uni != null) {
1620+
let xDistance = abs(mouseLeft0 - mouseLeft1);
1621+
let yDistance = abs(mouseTop0 - mouseTop1);
1622+
1623+
if (xDistance < uni)
1624+
dragX = false;
1625+
if (yDistance < uni)
1626+
dragY = false;
1627+
1628+
// neither x or y passed the threshold, we are in the magenta box (#219). In this
1629+
// scenario, we choose a unidirectional zoom based on which point is furthest from
1630+
// the origin M0
1631+
if (!dragX && !dragY) {
1632+
if (xDistance > yDistance)
1633+
dragX = true;
1634+
else
1635+
dragY = true;
1636+
}
1637+
}
1638+
1639+
if (dragX) {
16151640
let minX = min(mouseLeft0, mouseLeft1);
16161641
let maxX = max(mouseLeft0, mouseLeft1);
16171642
setStylePx(selectDiv, LEFT, select[LEFT] = minX);
16181643
setStylePx(selectDiv, WIDTH, select[WIDTH] = maxX - minX);
1644+
if (uni != null && !dragY) {
1645+
setStylePx(selectDiv, TOP, select[TOP] = 0);
1646+
setStylePx(selectDiv, HEIGHT, select[HEIGHT] = plotHgtCss);
1647+
}
16191648
}
16201649

1621-
if (drag.y) {
1650+
if (dragY) {
16221651
let minY = min(mouseTop0, mouseTop1);
16231652
let maxY = max(mouseTop0, mouseTop1);
16241653
setStylePx(selectDiv, TOP, select[TOP] = minY);
16251654
setStylePx(selectDiv, HEIGHT, select[HEIGHT] = maxY - minY);
1655+
if (uni != null && !dragX) {
1656+
setStylePx(selectDiv, LEFT, select[LEFT] = 0);
1657+
setStylePx(selectDiv, WIDTH, select[WIDTH] = plotWidCss);
1658+
}
16261659
}
16271660
}
16281661

0 commit comments

Comments
 (0)