'How to adjust the position of the ball in a ruler chart between measurements -100, 0, 100 inside the canvas?

There's a graph that has measurements ranging from -100 to 0 and 0 to 100. What I need to do is adjust the calculation of the ball's position with the number according to the gradientDataChart input, which can be a value between -100 and 100, the problem is proportionality, depending on the screen, the ball is disappearing, I was using distance 16, but it only worked for a width of 586px;

I tested it here if that might make it easier.

Just writing this code, I used 38 for 900 width, the problem is that if you change it to 1000, it goes out of position... it needs to be responsive:

var widthDefault = 900, metric = -100, calcPos = 38 * ((metric / widthDefault) * 100);
      ctx.beginPath();
      canvas.width = widthDefault;
      ctx.translate(calcPos, 0);
      var centerX = canvas.width / 2; 
      var centerY = canvas.height / 2;
      ctx.arc(centerX, centerY, 24, 0, Math.PI * 2, false);
      ctx.fillStyle ="#ffffff";
      ctx.fill()
      ctx.font = 'bold 14pt sans-serif';
      ctx.textAlign = 'center';
      ctx.strokeStyle ='#622BCF'
      ctx.stroke();
      ctx.fillStyle ="#622bcf80"; 
      ctx.fillText(`${medida}`, centerX, centerY+8);
      ctx.globalCompositeOperation = 'destination-over';

Image example: enter image description here



Solution 1:[1]

I'm not sure what you are doing in your calcPos, if you need something proportional you need to divide the width by the amount of points, your range is between -100 and 100, so we have 200 points, and we multiply that by the position on this case it is metric + 100...
X = width/200 * (metric + 100)

You can play with the code below:

var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");

function drawCircle(width, metric) {
  var X = width/200 * (metric + 100)
  var Y = canvas.height / 2;
  ctx.beginPath();
  ctx.arc(X, Y, 18, 0, Math.PI * 2, false);
  ctx.stroke();
  ctx.fillText(metric, X, Y);
}

drawCircle(canvas.width, -80)
drawCircle(canvas.width, -50)
drawCircle(canvas.width, 0)
drawCircle(canvas.width, 25)
drawCircle(canvas.width, 80)
<canvas id="c" width=300 height=140 style="border:solid 1px"></canvas>

Same code different canvas width:

var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");

function drawCircle(width, metric) {
  var X = width/200 * (metric + 100)
  var Y = canvas.height / 2;
  ctx.beginPath();
  ctx.arc(X, Y, 18, 0, Math.PI * 2, false);
  ctx.stroke();
  ctx.fillText(metric, X, Y);
}

drawCircle(canvas.width, -80)
drawCircle(canvas.width, -50)
drawCircle(canvas.width, 0)
drawCircle(canvas.width, 25)
drawCircle(canvas.width, 80)
<canvas id="c" width=600 height=140 style="border:solid 1px"></canvas>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1