Edit in JSFiddle

<div class="container">
  <svg id="chart" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 997">
    <defs>
      <pattern id="dot-pattern" x="-43" y="-19" width="65" height="50" patternUnits="userSpaceOnUse" viewBox="0 0 65 50">
        <rect width="65" height="50" fill="none"/>
        <circle cx="65" cy="50" r="2" fill="#fff" opacity="0.2"/>
        <circle cy="50" r="2" fill="#fff" opacity="0.2"/>
        <circle cx="65" r="2" fill="#fff" opacity="0.2"/>
        <circle r="2" fill="#fff" opacity="0.2"/>
      </pattern>
      <symbol id="marker-start-end" viewBox="0 0 47 47">
        <circle cx="23.5" cy="23.5" r="14" fill="#ff9b50"/>
        <circle cx="23.5" cy="23.5" r="23" fill="none" stroke="#ff9b50"/>
      </symbol>
    </defs>

    <rect id="bg-solid-color" width="1920" height="997" fill="#1e1e22"/>
    <rect id="bg-dot-pattern" width="1920" height="997" fill="url(#dot-pattern)"/>

    <path id="chart-line" d="M121,838s8,13,36,13c50.5,0,95.5-44,150-44,27,0,70.5,33.5,112.5,33.5s79-40,111-40,48,36,83,36c79,0,117-44,159-44s70,26,117,26c94,0,160-125,224-125,42,0,109-3,165-45,51.5-38.6,102-126,167-175,66.6-50.2,209-71,271-212" fill="none" stroke="#fff" stroke-width="4"/>
    
    <path id="chart-range" d="M121,838s8,13,36,13c50.5,0,95.5-44,150-44,27,0,70.5,33.5,112.5,33.5s79-40,111-40,48,36,83,36c79,0,117-44,159-44s70,26,117,26c94,0,160-125,224-125,42,0,109-3,165-45,51.5-38.6,102-126,167-175,66.6-50.2,209-71,271-212" fill="none" stroke="#ff9b50" stroke-width="8" stroke-dashoffset="1845.003662109375" stroke-dasharray="1845.003662109375"/>

    <use width="47" height="47" transform="translate(98 816)" xlink:href="#marker-start-end"/>
    <use width="47" height="47" transform="translate(1693 238)" xlink:href="#marker-start-end"/>

    <path id="slider" d="M-1,58S-7,70-26,70l10-9V19H-29L-1,0Zm2,0S7,70,26,70L16,61V19H29L1,0Z" fill="#ff9b50" transform="translate(121 863)"/>
  </svg>
</div>
body {
  margin: 0;
  padding: 0;
}

#slider {
  cursor: pointer;
}
const MAX_PATH_SEGMENTS_WIDTH = 2;
const sliderBottomOffset = 25;

const svg = document.querySelector('#chart');
const chartLine = document.querySelector('#chart-line');
const chartRange = document.querySelector('#chart-range');
const slider = document.querySelector('#slider');

const chartPoints = splitIntoSegments(chartLine, MAX_PATH_SEGMENTS_WIDTH);
const chartTotalLength = chartLine.getTotalLength();

chartRange.setAttributeNS(null, 'stroke-dasharray', chartTotalLength);
chartRange.setAttributeNS(null, 'stroke-dashoffset', -chartTotalLength);


slider.addEventListener('mousedown', function() {
	svg.addEventListener('mousemove', onMouseMove);
});

document.addEventListener('mouseup', function() {
	svg.removeEventListener('mousemove', onMouseMove);
});

function onMouseMove(e) {
  const {x: mouseX, y: mouseY} = svgPoint(svg, e.clientX, e.clientY);
  const chartSegment = calcIntersectionX(mouseX, chartPoints);
  
  let x, y, l;
  
  if (chartSegment[0] === chartSegment[1]) {
  	x = chartSegment[0].x;
    y = chartSegment[0].y;
    l = chartSegment[0].l;
  }
  else {
  	const dx = Math.abs(chartSegment[1].x - chartSegment[0].x);
    const xRatioOffset = (chartSegment[1].x - mouseX) / dx;
    const dy = Math.abs(chartSegment[1].y - chartSegment[0].y);
    const dl = Math.abs(chartSegment[1].l - chartSegment[0].l);
    x = mouseX;
    y = chartSegment[0].y + dy * xRatioOffset;
    l = chartSegment[0].l + dl * xRatioOffset;
  }
  
  slider.setAttributeNS(null, 'transform', `translate(${x} ${y + sliderBottomOffset})`);
  chartRange.setAttributeNS(null, 'stroke-dashoffset', `${chartTotalLength - l}`);
}

// translate page to SVG co-ordinate
function svgPoint(svg, x, y) {
  const pt = svg.createSVGPoint();
  pt.x = x;
  pt.y = y;
  return pt.matrixTransform(svg.getScreenCTM().inverse());
}

function splitIntoSegments(path, maxWidth = 2) {
  const pathLength = path.getTotalLength();
  const segmentsCount = Math.ceil(pathLength / maxWidth);

  const points = []
  for (let i = 0; i <= segmentsCount; i++) {
    const len = pathLength * i / segmentsCount;
    const pt = path.getPointAtLength(len);
    points.push({
      l: len,
      x: pt.x,
      y: pt.y,
    });
  }
  return points;
}

function calcIntersectionX(x, points) {
  let min = 0;
  let max = points.length - 1;

  if (x < points[min].x) {
  	return [points[min], points[min]];
  }
  if (x > points[max].x) {
  	return [points[max], points[max]];
  }

  while (min <= max) {
    let mid = min + max >> 1;
    let midValue = points[mid].x;

    if (midValue > x) {
      max = mid - 1;
    } else if (midValue < x) {
      min = mid + 1;
    } else {
      break;
    }
  }

  return [points[max], points[min]];
}