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))...