Reputation: 426
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.
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
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
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