Document
HTML
<div id="chart"></div>
<div id="chart2"></div>
<link
rel="stylesheet"
href="https://unpkg.com/[email protected]/dist/uPlot.min.css"
/>
<script src="https://unpkg.com/[email protected]/dist/uPlot.iife.min.js"></script>
CSS
#chart {
margin-bottom: 40px;
}
JavaScript
const data = [
[3, 3, 3, 5, 5],
[1, 2, 3, 1, 2],
[4, 5, 6, 2, 3],
];
const opts = {
title: "uPlot cursor demo",
width: 600,
height: 400,
series: [{},
{ label: "A",
paths: uPlot.paths.points(),
stroke: 'red'
},
{ label: "B",
paths: uPlot.paths.points(),
stroke: 'blue' }],
axes: [{
scale: 'x',
show: true
}, {
scale: 'y',
show: true
}],
scales: {
x: {
time: false,
min: 0,
max: 10
},
y: {
auto:true,
}
},
};
const el = document.getElementById("chart");
const u = new uPlot(opts, data, el);
const opts2 = { ...opts }
opts2.title = 'cursor.dataIdx overried'
opts2.cursor = {}
opts2.cursor = {
dataIdx: (u, seriesIdx, cursorIdx, valAtPosX) => {
if (seriesIdx === 0) return cursorIdx;
if (u?.series?.[seriesIdx]?.show === false) return null;
const xs = Array.isArray(u?.data?.[0]) ? u.data[0] : null;
const ys = Array.isArray(u?.data?.[seriesIdx]) ? u.data[seriesIdx] : null;
if (!xs || !ys) return null;
const len = Math.min(xs.length, ys.length);
if (len === 0) return cursorIdx;
const xOri = u.scales?.x?.ori || 0;
const pxY = xOri === 0 ? u.cursor.top : u.cursor.left;
if (!Number.isFinite(pxY)) return cursorIdx;
const baseIdx = cursorIdx;
const baseX = xs[baseIdx];
if (!Number.isFinite(baseX)) return cursorIdx;
const EPS = Math.max(1e-12, Math.abs(baseX) * 1e-12);
let L = baseIdx;
while (L - 1 >= 0 && Math.abs(xs[L - 1] - baseX) <= EPS) L -= 1;
let R = baseIdx;
while (R + 1 < len && Math.abs(xs[R + 1] - baseX) <= EPS) R += 1;
const scaleKey = u.series?.[seriesIdx]?.scale || "y";
let bestIdx = null;
let bestDy = Infinity;
for (let j = L; j <= R; j++) {
const yv = ys[j];
if (yv == null || Number.isNaN(yv)) continue;
const py = u.valToPos(yv, scaleKey);
if (!Number.isFinite(py))...