Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions demos/inside-css-zoom.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Inside CSS Zoom</title>
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="../dist/uPlot.min.css">
</head>
<body>
<script src="../dist/uPlot.iife.js"></script>

<div id="chart-wrap" style="zoom: 1.5; border: 2px dashed #ccc; padding: 10px; display: inline-block;">
<div id="chart"></div>
</div>

<br><br>

<label>CSS Zoom: <input id="zoomInput" type="number" value="1.5" step="0.25" min="0.25" max="5" style="width: 60px;"></label>
<button id="applyZoom">Apply Zoom</button>

<br><br>

<label><input id="autoDetect" type="checkbox"> Auto-detect (u.syncZoom() with no args)</label>

<script>
var n = 100, xs = [], ys = [], ys2 = [];
for (var i = 0; i < n; i++) {
xs[i] = i;
ys[i] = 50 + 30 * Math.sin(i * 0.1);
ys2[i] = 40 + 20 * Math.cos(i * 0.08);
}

var wrap = document.getElementById("chart-wrap");
var el = document.getElementById("chart");

var u = new uPlot({
width: 600,
height: 300,
title: "Inside CSS Zoom",
scales: {
x: { time: false },
},
series: [
{},
{ label: "Series A", stroke: "blue", width: 2 },
{ label: "Series B", stroke: "orange", width: 2 },
],
cursor: { show: true },
}, [xs, ys, ys2], el);

document.getElementById("applyZoom").onclick = function() {
var z = parseFloat(document.getElementById("zoomInput").value) || 1;
var auto = document.getElementById("autoDetect").checked;

wrap.style.zoom = z;

if (auto)
u.syncZoom(); // auto-detect from DOM
else
u.syncZoom(z); // explicit value, no DOM traversal
};
</script>
</body>
</html>
21 changes: 19 additions & 2 deletions src/uPlot.js
Original file line number Diff line number Diff line change
Expand Up @@ -3093,6 +3093,17 @@ export default function uPlot(opts, data, then) {
}

let rect = null;
let cssZoom = 1;

function getEffectiveZoom(el) {
let z = 1;
while (el) {
let s = getComputedStyle(el).zoom;
if (s && s !== 'normal') z *= parseFloat(s);
el = el.parentElement;
}
return z;
}

Object.defineProperty(self, 'rect', {
get() {
Expand All @@ -3108,6 +3119,7 @@ export default function uPlot(opts, data, then) {
rect = null;
else {
rect = over.getBoundingClientRect();
cssZoom = getEffectiveZoom(over);
fire("syncRect", rect);
}
}
Expand Down Expand Up @@ -3139,8 +3151,8 @@ export default function uPlot(opts, data, then) {
setCursorEvent(e);

if (e != null) {
_l = e.clientX - rect.left;
_t = e.clientY - rect.top;
_l = (e.clientX - rect.left) / cssZoom;
_t = (e.clientY - rect.top) / cssZoom;
}
else {
if (_l < 0 || _t < 0) {
Expand Down Expand Up @@ -3408,6 +3420,11 @@ export default function uPlot(opts, data, then) {
cursorPlots.add(self);

self.syncRect = syncRect;

// allows external code to notify uPlot when container CSS zoom changes,
// e.g. u.syncZoom() to auto-detect, or u.syncZoom(1.5) to set explicitly.
// avoids the performance cost of recalculating on every mousemove.
self.syncZoom = (z) => { cssZoom = z ?? getEffectiveZoom(over); };
}

// external on/off
Expand Down