JSFiddle - React, Tailwind, and code Playground

HTML

<html>
<body>

<input type="number" id="P" name="P" value="0"><input type="button" name="anim" id="anim" value="Animate progress bar"/>
<div style="width:100%;height:50px;background-color:grey">
<div id="output" style="width:0%;height:30px;padding-top:10px;background-color:green">
</div>
</div>
</body>
</html>

JavaScript

window.addEventListener("load", (ev) => {
  let euro_points = [0, 10, 80, 100]; //The milestones in euros
  let percent_points = [0, 25, 50, 100]; //The milestones in percent on the scale
  let p = document.getElementById("P");
  let o = document.getElementById("output");
  p.addEventListener("change", () => {
    o.innerHtml = p.value;
    //Find the highest euro_points variable which is still smaller than the input value
    let i = 0;
    for (i = 0; i < euro_points.length; i++) {
      if (euro_points[i] > p.value)
        break;
    }
    //we are 1 too high
    i = i - 1;
    if (i == euro_points.length - 1) { // We hit the top, do whatever you want, if you do nothing, you access euro_points and percent_points past the array size
      o.style.width = "100%";
      o.style["background-color"] = "blue";
      o.innerText = "Saturate at highest level";
      return;
    }
    //Compute a linear regression between the two nearest points
    let p_val = percent_points[i] + (p.value - euro_points[i]) / (euro_points[i + 1] - euro_points[i]) * (percent_points[i + 1] - percent_points[i]);
    //Visualize
    o.style["background-color"] = "green";
    o.style.width = p_val + "%";
    o.innerText = p.value + " i=" + i;
  });

  //animation, not relevant, only for demonstration
  let do_anim = false;
  document.getElementById("anim").addEventListener("click", () => {
    do_anim ^= true;
  });
  window.setInterval(() => {
    if (do_anim) {
      if (p.value >= 150) {
        p.value = 0;
      } else {
        p.value -= -0.5;
      }
      p.dispatchEvent(new Event("change"));
    }
  }, 50);
});