uPlot ranger是轻量高性能局部放大方案,通过缩略图联动、禁用Y轴同步、反算数据值锚点缩放等实现精准交互。

直接用 uPlot 的范围选择器(ranger)或滚轮缩放插件,配合 sync 配置同步主图视图,是目前最轻量、高性能的局部放大方案。硬套 CSS transform: scale() 或 canvas 手动重绘,只会导致坐标错乱、交互失灵、文字糊成一片。
用 uPlot ranger 实现拖拽局部放大
核心是把一个独立的 uPlot 实例作为“缩略图”,绑定 setSelect 和 hooks.select 与主图联动。它不渲染完整数据,只画坐标轴和粗略趋势线,性能开销极低。
- 必须在
rangerOpts中设cursor.drag.x = true且y = false,否则会误触发 Y 轴缩放,破坏时间序列逻辑 -
hooks.ready里调uRanger.setSelect({left, width, height}, false)是初始化关键——false表示不触发后续回调,避免首次加载时主图被意外重绘 - 主图的
sync配置要显式写sync: { key: "ranger", scales: { x: true, y: false } },Y 轴禁同步,防止数值型图表(如温度)被缩略图拉偏 - 如果 ranger 区域太窄(比如小于 5 像素),
uPlot默认不触发select,需手动监听mousedown/mouseup补充最小宽度判断
鼠标滚轮缩放时保持焦点位置不变
默认滚轮缩放以画布中心为锚点,但用户实际想“放大鼠标指针下的数据点”。这需要把像素坐标反算成数据值,再重新计算缩放后的新范围。
- 监听
wheel事件后,先用u.posToVal(left, "x")把鼠标 X 坐标转为原始数据值(不是像素) - 不要直接用
e.deltaY算像素偏移——不同设备滚轮灵敏度差异大,应统一按比例缩放:nxRange = oxRange * (e.deltaY - 新
xMin必须基于当前鼠标对应的数据值计算:nxMin = xVal - leftPct * nxRange,其中leftPct = (left - u.bbox.left) / u.bbox.width,确保锚点精准 - 缩放后立即调
u.setScale("x", { min: nxMin, max: nxMin + nxRange }),别漏掉u.redraw(),否则 UI 不更新
缩放后 SVG 图表组件坐标系别崩了
如果你在仪表盘里混用了 uPlot 和自定义 SVG 组件(比如状态环、指标卡片),缩放主图时这些 SVG 很容易位置偏移或尺寸错乱——因为它们没参与 uPlot 的坐标系统。
- 所有 SVG 组件的容器必须设
viewBox="0 0 800 600",删掉width/height属性,否则缩放会覆盖 viewBox 行为 - SVG 内部所有坐标计算(比如柱状图的
y值)必须封装进组件内部,调用方只传原始数据,不传像素值;严禁让使用者自己写y = height - value * scale - 若 SVG 需随主图缩放联动(比如高亮某时段背景色),不要用 JS 动态改
transform,而应在uPlot的hooks.draw里用u.valToPos()把数据值实时转为画布像素,再注入 SVG的x/y/width/height - 字体模糊?给 SVG 容器加
transform: translateZ(0),同时确保的font-size用em,不用px
真正卡住人的从来不是“怎么放大”,而是放大后坐标对不上、SVG 锚点飘走、滚轮一划就跳到三天前——这些细节藏在 posToVal 和 valToPos 的调用时机里,也藏在 viewBox 和 transform-origin 的取舍之间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











