Skip to content

Commit

Permalink
during size changes, silently sync the DOM of cursor, select, hover p…
Browse files Browse the repository at this point in the history
…ts. close #875.
  • Loading branch information
leeoniya committed Dec 20, 2023
1 parent 917f830 commit 3c1ba3b
Show file tree
Hide file tree
Showing 7 changed files with 357 additions and 89 deletions.
1 change: 1 addition & 0 deletions demos/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ <h1>μPlot Demos</h1>
<a href="gradients.html">Gradient fills &amp; strokes (vt &amp; hz, scale-affixed &amp; data-relative)</a>
<a href="scales-dir-ori.html">Scale direction &amp; orientation (e.g. rotation, inversion)</a>
<a href="y-scale-drag.html">Draggable y scales via axes</a>
<a href="update-cursor-select-resize.html">Maintains location of cursor/select/hoverPts during resize (test)</a>

<a href="months-ru.html">Russian month names on date/time axis</a>
<a href="add-del-series.html">Dynamically add or delete series</a>
Expand Down
75 changes: 75 additions & 0 deletions demos/update-cursor-select-resize.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Keep selection and cursor in sync with resize (test)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="../dist/uPlot.min.css">
</head>
<body>
<script type="module">
import uPlot from "../dist/uPlot.esm.js";

let data = [
[0,1,2],
[0,1,2],
];

const opts = {
title: "Maintain loc of cursor/select/hoverPts",
width: 800,
height: 800,
scales: {
x: {
time: false,
},
},
series: [
{},
{
stroke: "red",
fill: "rgba(255,0,0,0.1)",
},
],
};

let u = new uPlot(opts, data, document.body);

setTimeout(() => {
u.setCursor({left: 200, top: 200});
u.cursor._lock = true;
u.setSelect({
top: 0,
height: u.bbox.height / uPlot.pxRatio,
left: 100,
width: 100,
});
});

let dir = -1;
let incr = 10;
let minSize = 400;
let maxSize = 800;

let size = maxSize;

setInterval(() => {
if (dir == -1 && size < minSize) {
dir = 1;
size = minSize;
return;
}
else if (dir == 1 && size > maxSize) {
dir = -1;
size = maxSize;
return;
}

size += dir * incr;

u.setSize({width: size, height: size});
}, 100);
</script>
</body>
</html>
92 changes: 70 additions & 22 deletions dist/uPlot.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3214,6 +3214,13 @@ function uPlot(opts, data, then) {
let plotLftCss = 0;
let plotTopCss = 0;

// previous values for diffing
let _plotLftCss = plotLftCss;
let _plotTopCss = plotTopCss;
let _plotWidCss = plotWidCss;
let _plotHgtCss = plotHgtCss;


let plotLft = 0;
let plotTop = 0;
let plotWid = 0;
Expand All @@ -3237,9 +3244,6 @@ function uPlot(opts, data, then) {
shouldConvergeSize = true;
shouldSetSize = true;

if (cursor.left >= 0)
shouldSetCursor = shouldSetLegend = true;

commit();
}

Expand Down Expand Up @@ -3267,11 +3271,6 @@ function uPlot(opts, data, then) {
const CYCLE_LIMIT = 3;

function convergeSize() {
let _plotLft = plotLft;
let _plotTop = plotTop;
let _plotWid = plotWid;
let _plotHgt = plotHgt;

let converged = false;

let cycleNum = 0;
Expand All @@ -3287,15 +3286,6 @@ function uPlot(opts, data, then) {
if (!converged) {
calcSize(self.width, self.height);
shouldSetSize = true;

if (
plotLft != _plotLft ||
plotTop != _plotTop ||
plotWid != _plotWid ||
plotHgt != _plotHgt
) {
resetYSeries(false);
}
}
}
}
Expand Down Expand Up @@ -3411,6 +3401,9 @@ function uPlot(opts, data, then) {

// series-intersection markers
let cursorPts = [null];
// position caches in CSS pixels
let cursorPtsLft = [null];
let cursorPtsTop = [null];

function initCursorPt(s, si) {
if (si > 0) {
Expand Down Expand Up @@ -3476,7 +3469,12 @@ function uPlot(opts, data, then) {
activeIdxs.splice(i, 0, null);

let pt = initCursorPt(s, i);
pt && cursorPts.splice(i, 0, pt);

if (pt != null) {
cursorPts.splice(i, 0, pt);
cursorPtsLft.splice(i, 0, 0);
cursorPtsTop.splice(i, 0, 0);
}
}

fire("addSeries", i);
Expand Down Expand Up @@ -3508,7 +3506,11 @@ function uPlot(opts, data, then) {
if (cursor.show) {
activeIdxs.splice(i, 1);

cursorPts.length > 1 && cursorPts.splice(i, 1)[0].remove();
if (cursorPts.length > 1) {
cursorPts.splice(i, 1)[0].remove();
cursorPtsLft.splice(i, 1);
cursorPtsTop.splice(i, 1);
}
}

// TODO: de-init no-longer-needed scales?
Expand Down Expand Up @@ -4583,6 +4585,47 @@ function uPlot(opts, data, then) {

syncRect(true);

if (
plotLftCss != _plotLftCss ||
plotTopCss != _plotTopCss ||
plotWidCss != _plotWidCss ||
plotHgtCss != _plotHgtCss
) {
resetYSeries(false);

let pctWid = plotWidCss / _plotWidCss;
let pctHgt = plotHgtCss / _plotHgtCss;

if (cursor.show && !shouldSetCursor && cursor.left >= 0) {
cursor.left *= pctWid;
cursor.top *= pctHgt;

vCursor && elTrans(vCursor, round(cursor.left), 0, plotWidCss, plotHgtCss);
hCursor && elTrans(hCursor, 0, round(cursor.top), plotWidCss, plotHgtCss);

for (let i = 1; i < cursorPts.length; i++) {
cursorPtsLft[i] *= pctWid;
cursorPtsTop[i] *= pctHgt;
elTrans(cursorPts[i], incrRoundUp(cursorPtsLft[i], 1), incrRoundUp(cursorPtsTop[i], 1), plotWidCss, plotHgtCss);
}
}

if (select.show && !shouldSetSelect && select.left >= 0 && select.width > 0) {
select.left *= pctWid;
select.width *= pctWid;
select.top *= pctHgt;
select.height *= pctHgt;

for (let prop in _hideProps)
setStylePx(selectDiv, prop, select[prop]);
}

_plotLftCss = plotLftCss;
_plotTopCss = plotTopCss;
_plotWidCss = plotWidCss;
_plotHgtCss = plotHgtCss;
}

fire("setSize");

shouldSetSize = false;
Expand Down Expand Up @@ -5065,11 +5108,11 @@ function uPlot(opts, data, then) {

activeIdxs[i] = idx2;

let xPos2 = incrRoundUp(idx2 == idx ? xPos : valToPosX(mode == 1 ? data[0][idx2] : data[i][0][idx2], scaleX, xDim, 0), 1);
let xPos2 = idx2 == idx ? xPos : valToPosX(mode == 1 ? data[0][idx2] : data[i][0][idx2], scaleX, xDim, 0);

if (i > 0 && s.show) {
// this doesnt really work for state timeline, heatmap, status history (where the value maps to color, not y coords)
let yPos = yVal2 == null ? -10 : incrRoundUp(valToPosY(yVal2, mode == 1 ? scales[s.scale] : scales[s.facets[1].scale], yDim, 0), 1);
let yPos = yVal2 == null ? -10 : valToPosY(yVal2, mode == 1 ? scales[s.scale] : scales[s.facets[1].scale], yDim, 0);

if (cursorFocus && mode == 1 && yVal2 != null) {
let dist = abs(focus.dist(self, i, idx2, yPos, mouseTop1));
Expand Down Expand Up @@ -5136,8 +5179,13 @@ function uPlot(opts, data, then) {
ptWid = ptHgt = cursor.points.size(self, i);
}


elSize(cursorPts[i], ptWid, ptHgt, centered);
elTrans(cursorPts[i], ptLft, ptTop, plotWidCss, plotHgtCss);

cursorPtsLft[i] = ptLft;
cursorPtsTop[i] = ptTop;

elTrans(cursorPts[i], incrRoundUp(ptLft, 1), incrRoundUp(ptTop, 1), plotWidCss, plotHgtCss);
}
}
}
Expand Down
Loading

0 comments on commit 3c1ba3b

Please sign in to comment.