haacki47
haacki47

Reputation: 426

How to represent any numbers in chart via canvas?

I want to create line chart via canvas, for data representation on vanilla JavaScript. For example canvas width 600px, height 400px. I have min and max possible numbers on Y axis and numbers between them. X axis represents date.

line chart example

This chart has maximum 1000 and minimum 0 (and numbers between them). I can use this numbers to draw dots in pixels on canvas. But if in future data maximum number will 75 and minumum 10, i should redraw dots on chart in pixels again in possible range.

The problem is how to translate any numbers from 0 to 1000, 10 to 75, 2k to 8k and so on to pixels to draw it on canvas to represent them, in 600px on 400px? or in 800px on 600px ?

For simple example. I have canvas 600x400px. I have range of numbers from 0 to 1000. 1000 equals 400px it's placed on top of chart. 0 is 0 pixels placed on bottom of the chart. How much will 768 in pixels for example? What formula is here? How to translate numbers of any size to pixels?

Could explain how to achive that result? Maybe code samples or formulas

Upvotes: 2

Views: 553

Answers (2)

Darth
Darth

Reputation: 1651

const ctx = canvas.getContext('2d');
const padding = 10;
const settings = {
   x: {min: 0, max: 1000, step: 200}, 
   y: {min: 0, max: 10, step: 2},
   width: 600,
   height: 400
};


class Chart{
  constructor(canvas, settings){
    canvas.width = settings.width;
    canvas.height = settings.height;

    // offsets for labels
    const offsetX = Math.ceil(Math.max(
      ctx.measureText(settings.y.min.toString()).width, 
      ctx.measureText(settings.y.max.toString()).width
    ));
    const offsetY = Math.ceil(ctx.measureText("1").actualBoundingBoxAscent + ctx.measureText("1").actualBoundingBoxDescent);

    // origin position in pixels
    const originX = offsetX + padding;
    const originY = settings.height - padding - offsetY

    // step size in pixels
    const stepXPx = (settings.width - padding - originX) / ((settings.x.max - settings.x.min)/settings.x.step);
    const stepYPx = (originY - padding) / ((settings.y.max - settings.y.min)/settings.y.step);

    // axises
    ctx.fillRect(originX, padding, 1, originY - padding);
    ctx.fillRect(originX, originY,canvas.width - padding - originX, 1);

    // dots and labels X
    for(
      let x = settings.x.min, step = 0; 
      x <= settings.x.max; 
      x += settings.x.step, step++
    ){
      const xPx = originX + step * stepXPx; // calc pos in pixels
      ctx.fillRect(xPx - 1, originY - 4, 2, 8);
      ctx.fillText(x, xPx - padding, originY + offsetY + padding)
    }

    // dots and labels Y
    for(
      let y = settings.y.min, step = 0; 
      y <= settings.y.max; 
      y += settings.y.step, step++
    ){
      const yPx = originY - step * stepYPx; // calc pos in pixels
      ctx.fillRect(originX - 4, yPx - 1, 8 , 2);
      ctx.fillText(y, originX - offsetX, yPx + offsetY/2);
    }
  }
  
}


new Chart(canvas, settings);

// another example
setTimeout(() => {
  new Chart(canvas, {
   x: {min: -4, max: 4, step: .5},
   y: {min: 160000, max: 1000000, step: 80000}, 
   width: 400,
   height: 300
  });
}, 6000)
<canvas id=canvas></canvas>

Upvotes: 0

joaovzg
joaovzg

Reputation: 50

To find the Y axis in px the formula woulde be:
px to be find = (present value * max px)/max value
Ex:
X = (550*400)/1000 =>
X = 220,000/1,000 =>220 (that's you px value to the Y axis)

The X axis is just a default distance that you set, at least that's what I understood by your question.

Upvotes: 1

Related Questions