I am new to javascript so sorry if my mistake is obvious! I am trying to draw an ellipse using the canonical form equation.
<html>
<body>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #000000;">
</canvas>
<script language="javaScript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var HEIGHT = ctx.height;
var WIDTH = ctx.width;
function transform(p){
return [ WIDTH/2 + p[0], HEIGHT/2 - p[1]];
}
var a = 70; //length parallel to x axis
var b = 30; //length parallel to y axis
var h = 150 - WIDTH/2; //when tranformed this gives the pixel 150
var k = -HEIGHT/2 - 100; //when transformed this gives pixel 100
function y(x){
return b*Math.sqrt(1 - Math.pow((x - h)/a, 2)) + k;
}
var dx = a/2/100 ; //each quadrant is broken into 100 segments
var pOld = [h - a/2, k]; //starting point
var pNew = [0,0];
var x1 = 0;
var x2 = 0;
var y1 = 0;
var y2 = 0;
var temp = [0,0];
for (var i = 0; i < 100; ++i){
pNew[0] = pOld[0] + dx;
pNew[1] = y(pNew[0]);
temp = transform(pOld);
x1 = temp[0]; y1 = temp[1];
temp = transform(pNew);
x2 = temp[0]; y2 = temp[1];
ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); //x1, y1 -> x2, y2
ctx.moveTo(x1, -y1); ctx.lineTo(x2, -y2); //x1,-y1 -> x2,-y2
ctx.moveTo(-x1, y1); ctx.lineTo(-x2, y2); //-x1,y1 -> -x2, y2
ctx.moveTo(-x1, -y1); ctx.lineTo(-x2, -y2); //-x1,-y1 -> -x2,-y2
pOld = pNew;
}
ctx.lineWidth = 2;
ctx.strokeStyle = "#232323";
ctx.stroke();
</script>
</body>
</html>
You values are NaN (Not-a-Number). Change these lines:
var HEIGHT = ctx.height;
var WIDTH = ctx.width;
to
var HEIGHT = c.height;
var WIDTH = c.width;
and you get proper Numbers. However, your y value is outside the canvas area - you will see this if you console.log the values. There seem to be some issues with the math in general which I don't address here, but in relation to canvas you should be one step further.
Related
This question already has an answer here:
how to draw smooth lines on canvas without clearing it?
(1 answer)
Closed 5 months ago.
This post was edited and submitted for review 5 months ago and failed to reopen the post:
Original close reason(s) were not resolved
For horizontal and vertical lines, using translation of 0.5 for odd stroke widths produces crisper/sharper lines. How about the diagonal lines?
Link to jsfiddle
<!DOCTYPE html>
<html lang="en">
<body style="background: black">
<button id="btn">Draw Next Line</button>
<br>
<canvas style="border: 2px solid red" id="cnv"></canvas>
<script>
const ctx = document.getElementById("cnv").getContext("2d");
debugger;
const delta = 25;
const color = 'white';
const W = window.innerWidth - 80;
const H = window.innerHeight - 100;
ctx.canvas.width = W;
ctx.canvas.height = H;
ctx.lineWidth = 1;
ctx.strokeStyle = color;
// diagonal line.
ctx.moveTo(0.5, 0);
ctx.lineTo(W, H);
ctx.stroke();
// vertical lines
let i = 0.5;
document.getElementById("btn").onclick = () => {
ctx.moveTo(i * delta, 0);
ctx.lineTo(i * delta, H);
ctx.stroke();
i++;
}
</script>
</body>
</html>
As can be seen on the demo, after adding another line previously drawn diagonal lines get bolder or thicker.
How to get consistent thickness/sharpness irrespective of whether the diagonal line is drawn first or last?
You're missing a ctx.beginPath(); call before each new line:
<!DOCTYPE html>
<html lang="en">
<body style="background: black">
<button id="btn">Draw Next Line</button>
<br>
<canvas style="border: 2px solid red" id="cnv"></canvas>
<script>
const ctx = document.getElementById("cnv").getContext("2d");
debugger;
const delta = 25;
const color = 'white';
const W = window.innerWidth - 80;
const H = window.innerHeight - 100;
ctx.canvas.width = W;
ctx.canvas.height = H;
ctx.lineWidth = 1;
ctx.strokeStyle = color;
// diagonal line.
ctx.moveTo(0.5, 0);
ctx.lineTo(W, H);
ctx.stroke();
// vertical lines
let i = 0.5;
document.getElementById("btn").onclick = () => {
ctx.beginPath(); // <------------------------ Here
ctx.moveTo(i * delta, 0);
ctx.lineTo(i * delta, H);
ctx.stroke();
i++;
}
</script>
</body>
</html>
I would research a bit and draw a line manually using pixels and some online algorithm. This also involves special pixel function because we don't want the same effect over each pixel.
Found this function draw_line taken from here
.
var canvas = document.querySelector("canvas");
var ctx = canvas.getContext('2d');
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
var r = 255
var g = 255
var b = 255
function pixel(x, y) {
var id = ctx.createImageData(1, 1); // only do this once per page
var d = id.data; // only do this once per page
d[0] = r;
d[1] = g;
d[2] = b;
d[3] = 255;
ctx.putImageData(id, x, y);
}
let draw_line = (x1, y1, x2, y2) => {
// Iterators, counters required by algorithm
let x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
// Calculate line deltas
dx = x2 - x1;
dy = y2 - y1;
// Create a positive copy of deltas (makes iterating easier)
dx1 = Math.abs(dx);
dy1 = Math.abs(dy);
// Calculate error intervals for both axis
px = 2 * dy1 - dx1;
py = 2 * dx1 - dy1;
// The line is X-axis dominant
if (dy1 <= dx1) {
// Line is drawn left to right
if (dx >= 0) {
x = x1;
y = y1;
xe = x2;
} else { // Line is drawn right to left (swap ends)
x = x2;
y = y2;
xe = x1;
}
pixel(x, y); // Draw first pixel
// Rasterize the line
for (i = 0; x < xe; i++) {
x = x + 1;
// Deal with octants...
if (px < 0) {
px = px + 2 * dy1;
} else {
if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) {
y = y + 1;
} else {
y = y - 1;
}
px = px + 2 * (dy1 - dx1);
}
// Draw pixel from line span at
// currently rasterized position
pixel(x, y);
}
} else { // The line is Y-axis dominant
// Line is drawn bottom to top
if (dy >= 0) {
x = x1;
y = y1;
ye = y2;
} else { // Line is drawn top to bottom
x = x2;
y = y2;
ye = y1;
}
pixel(x, y); // Draw first pixel
// Rasterize the line
for (i = 0; y < ye; i++) {
y = y + 1;
// Deal with octants...
if (py <= 0) {
py = py + 2 * dx1;
} else {
if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) {
x = x + 1;
} else {
x = x - 1;
}
py = py + 2 * (dx1 - dy1);
}
// Draw pixel from line span at
// currently rasterized position
pixel(x, y);
}
}
}
for (var i = 0; i < 50; i++) {
draw_line(0, 0, 50, 100)
}
<canvas></canvas>
Refer to this fiddle:
// get canvas references (canvas=collar, canvas1=texture)
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var canvas1 = document.getElementById("canvas1");
var ctx1 = canvas1.getContext("2d");
// preload the texture and collar images before starting
var textureImg, collarImg;
var imageURLs = [];
var imagesOK = 0;
var imgs = [];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/checkered.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/collar.png");
loadAllImages();
function loadAllImages(callback) {
for (var i = 0; i < imageURLs.length; i++) {
var img = new Image();
img.crossOrigin = "anonymous";
imgs.push(img);
img.onload = function () {
imagesOK++;
if (imagesOK == imageURLs.length) {
textureImg = imgs[0];
collarImg = imgs[1];
start();
}
};
img.src = imageURLs[i];
}
}
function start() {
// set both canvas dimensions
canvas.width = collarImg.width;
canvas.height = collarImg.height + 5;
canvas1.width = textureImg.width;
canvas1.height = textureImg.height;
// draw the textureImg on canvas1
ctx1.drawImage(textureImg, 0, 0, canvas1.width, canvas1.height);
// curve the texture into a collar shaped curved
curveTexture(collarImg.width, collarImg.height);
// draw the collarImg on canvas
ctx.drawImage(collarImg, 0, 0);
// set compositing to source-atop
// any new drawing will ONLY fill existing non-transparent pixels
ctx.globalCompositeOperation = "source-atop";
// draw the curved texture from canvas1 onto the collar of canvas
// (the existing pixels are the collar, so only the collar is filled)
ctx.drawImage(canvas1, 0, 0);
}
function curveTexture(w, h) {
// define a quadratic curve that fits the collar bottom
// These values change if the collar image changes (+5,-32)
var x0 = 0;
var y0 = h + 5;
var cx = w / 2;
var cy = h - 32;
var x1 = w;
var y1 = h + 5;
// get a,b,c for quadratic equation
// equation is used to offset columns of texture pixels
// in the same shape as the collar
var Q = getQuadraticEquation(x0, y0, cx, cy, x1, y1);
// get the texture canvas pixel data
// 2 copies to avoid self-referencing
var imageData0 = ctx1.getImageData(0, 0, w, h);
var data0 = imageData0.data;
var imageData1 = ctx1.getImageData(0, 0, w, h);
var data1 = imageData1.data;
// loop thru each vertical column of pixels
// Offset the pixel column into the shape of the quad-curve
for (var y = 0; y < h; y++) {
for (var x = 0; x < w; x++) {
// the pixel to write
var n = ((w * y) + x) * 4;
// the vertical offset amount
var yy = parseInt(y + h - (Q.a * x * x + Q.b * x + Q.c));
// the offset pixel to read
var nn = ((w * yy) + x) * 4;
// offset this pixel by the quadCurve Y value (yy)
data0[n + 0] = data1[nn + 0];
data0[n + 1] = data1[nn + 1];
data0[n + 2] = data1[nn + 2];
data0[n + 3] = data1[nn + 3];
}
}
ctx1.putImageData(imageData0, 0, 0);
}
// Quadratic Curve: given x coordinate, find y coordinate
function getQuadraticY(x, Q) {
return (Q.a * x * x + Q.b * x + Q.c);
}
// Quadratic Curve:
// Given: start,control,end points
// Find: a,b,c in quadratic equation ( y=a*x*x+b*x+c )
function getQuadraticEquation(x0, y0, cx, cy, x2, y2) {
// need 1 more point on q-curve, so calc its midpoint XY
// Note: since T=0.5 therefore TT=(1-T)=0.5 also [so could simplify]
var T = 0.50;
var TT = 1 - T;
var x1 = TT * TT * x0 + 2 * TT * T * cx + T * T * x2;
var y1 = TT * TT * y0 + 2 * TT * T * cy + T * T * y2;
var A = ((y1 - y0) * (x0 - x2) + (y2 - y0) * (x1 - x0)) / ((x0 - x2) * (x1 * x1 - x0 * x0) + (x1 - x0) * (x2 * x2 - x0 * x0));
var B = ((y1 - y0) - A * (x1 * x1 - x0 * x0)) / (x1 - x0);
var C = y0 - A * x0 * x0 - B * x0;
return ({
a: A,
b: B,
c: C
});
}
body {
background-color: ivory;
padding:20px;
}
canvas {
border:1px solid red;
}
<h3>"Curve" a texture</h3>
<p>by offsetting Y pixels based on Q-curve</p>
<canvas id="canvas" width=300 height=300></canvas>
<p>The temporary texture canvas (canvas1)</p>
<canvas id="canvas1" width=300 height=300></canvas>
http://jsfiddle.net/m1erickson/hdXyk/
I want to convert that horizontal generated lines to vertical. I tries to change the values but unable to achieved it.
I think that "Curve" a texture by offsetting X pixels based on Q-curve might work for getting vertical lines. Please help me for this.
For more you can refer this link : How to fill pattern in canvas and curving along the shape?
I have drawn a grid in html5 canvas using StrokeLineX and StrokeLineY. I want to highlight the particular square/rectangle when I click on it in the grid.
I have tried using math.floor to define an index for a space but as soon as the width or height increases it starts giving different answers. I have tried too many times before finally posting it here.
Here is the code.
var canvas = document.getElementById("myCanvas");
canvas.addEventListener('click', on_canvas_click, false);
var ctx = canvas.getContext("2d");
var tray_length = 800;
var tray_depth = 800;
var boxHeight = 50;
var boxWidth = 50;
var canvas_X = tray_length;
var canvas_Y = tray_depth;
var box_x_pixels = canvas_X/no_of_columns;
var box_y_pixels = canvas_Y/no_of_rows;
// Drawing the grid
for (var y = boxWidth; y < canvas_Y; y += boxWidth) {
strokeLineX(ctx, y);
}
for (var x = boxHeight; x < canvas_X; x += boxHeight) {
strokeLineY(ctx, x);
}
function strokeLineX(ctx, y) {
ctx.beginPath();
ctx.strokeStyle = 'green';
ctx.moveTo(0, y);
ctx.lineTo(canvas_X, y);
ctx.stroke();
ctx.closePath();
}
function strokeLineY(ctx, x) {
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo(x, 0);
ctx.lineTo(x, canvas_Y);
ctx.stroke();
ctx.closePath();
}
function on_canvas_click(ev) {
var x = ev.pageX - canvas.offsetLeft;
var y = ev.pageY - canvas.offsetTop;
console.log(x+":"+y);
var coordinateDisplay = "x=" + x + ", y=" + y;
if (y>= 0 && y <= y+boxHeight ) {
var indexOfX = Math.floor(x/boxWidth); //divide on width and round off
var indexOfY = Math.floor(y/boxHeight);
// alert('You clicked bar index: ' + indexOfX+"-"+indexOfY);
ctx.fillRect="green";
ctx.rect(x,y,box_x_pixels,box_y_pixels);
ctx.stroke();
console.log(indexOfX + "-" + indexOfY);
}
}
In on_canvas_click change the following:
Instead of
ctx.fillRect="green";
do:
ctx.fillStyle="green";
And instead of:
ctx.rect(x,y,box_x_pixels,box_y_pixels);
do:
ctx.fillRect(boxWidth*indexOfX, boxHeight*indexOfY, boxWidth, boxHeight);
... and you don't need:
ctx.stroke();
Here is a working snippet with those changes applied, but also with some simplifications which are unrelated to your problem:
Removal of unused variables;
Use of one function to draw lines, instead of two;
Use of canvas.width and canvas.height properties;
Drawing grid lines also on the outer grid boundaries
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var boxHeight = 50;
var boxWidth = 50;
var canvas_X = canvas.width;
var canvas_Y = canvas.height;
canvas.addEventListener('click', on_canvas_click, false);
// Drawing the grid
for (var y = 0; y <= canvas_Y; y += boxWidth) {
strokeLine(ctx, 0, y, canvas_X, y, 'green');
}
for (var x = 0; x <= canvas_X; x += boxHeight) {
strokeLine(ctx, x, 0, x, canvas_Y, 'red');
}
function strokeLine(ctx, x0, y0, x1, y1, color) {
ctx.beginPath();
ctx.strokeStyle = color;
ctx.moveTo(x0, y0);
ctx.lineTo(x1, y1);
ctx.stroke();
ctx.closePath();
}
function on_canvas_click(ev) {
var x = ev.pageX - canvas.offsetLeft;
var y = ev.pageY - canvas.offsetTop;
if (y>= 0 && y <= y+boxHeight ) {
var indexOfX = Math.floor(x/boxWidth); //divide on width and round off
var indexOfY = Math.floor(y/boxHeight);
ctx.fillStyle="green";
ctx.fillRect(boxWidth*indexOfX, boxHeight*indexOfY, boxWidth, boxHeight);
}
}
<canvas id="myCanvas" width="600" height="200"></canvas>
I'm learning how to use canvas and I wanted to make a painting app. I can easily draw lines and shapes, but I can't understand how to change the width of a line from a specified size to one another with the same line.
I would like to do something like:
Draw a line from point (0, 1) to point (10, 10) and size from 10 to 5
Is it possible?
try this, the idea is to draw several lines
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
function drawline(xo,yo,xf,yf,wo,wf, parts){
var stepX = (xf-xo)/parts;
var stepY = (yf-yo)/parts;
var stepW = (wf-wo)/parts;
for(var i=1; i<=parts; ++i){
ctx.beginPath();
ctx.lineWidth = wo + stepW*i;
ctx.moveTo(xo+stepX*(i-1), yo+stepY*(i-1));
ctx.lineTo(xo+stepX*i, yo+stepY*i);
ctx.stroke();
}
}
drawline(10,10,150,150,1,10, 100);
drawline(10,10,150,300,1,10, 100);
<canvas id="canvas1" width="500" height="500">
</canvas>
or, a solution better, using trapezoids (no general solution shows)
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
function drawline(xo,yo,xf,yf,wo,wf){
//if xf == xo vertical line, failure ;)
var m = (yf-yo)/(xf-xo);
//if m==0, horizontal line, failure
var mp = -1 / m;
var angle = Math.atan(mp);
var dy1 = Math.sin(angle) * wo/2;
var dx1 = Math.cos(angle) * wo/2;
var dy2 = Math.sin(angle) * wf/2;
var dx2 = Math.cos(angle) * wf/2;
//depending on the positions of xo,yo,xf and yf change signs
//this isn't a general solution
//solution for xo<xf and yo<yf
var x1 = xo + dx1;
var y1 = yo + dy1;
var x2 = xo - dx1;
var y2 = yo - dy1;
var x3 = xf - dx2;
var y3 = yf - dy2;
var x4 = xf + dx2;
var y4 = yf + dy2;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.lineTo(x4, y4);
ctx.fill();
}
drawline(10,10,150,150,1,10);
drawline(10,10,150,300,1,10);
<canvas id="canvas1" width="500" height="500">
</canvas>
I am making a program that graphs a line based on data inputted by the user. (It's based on the slope form/equation). I am using the Canvas to graph my equation. I've been having a problem graphing the equation in a way that lets it adapt to the scaling (which is based on how large the numbers inputted are.)
How can I make the graphed equation (line) fit the graph as the canvas scales?
Here's my code:
var c=document.getElementById("graph_");
var ctx=c.getContext("2d");
graph_.style.backgroundColor="white";
// This is used to define the parameters of the canvas. Variables a and b are the x and y intercepts of the linear function.
var z0=Math.max(Math.abs(a),Math.abs(b));
var z=Math.round(z0);
var z1=Math.round(z);
var z2=z*2
// alert(z1);
// alert(z2);`
//The code below is used to properly scale the canvas and lines so they can accomodate larger numbers
var scale = 2*z/360;
var offsetX = 150;
var offsetY = 75
ctx.translate((-c.width /2 * scale) + offsetX,(-c.height / 2 * scale) + offsetY);
ctx.scale(scale,scale);
var lw = scale/2
var xnew = 360/2+360/2*a
var ynew = 360/2-360/2*b
alert(xnew);
alert(ynew);
//The two lines drawn below are the axises of the graph
ctx.lineWidth = 2/lw;
ctx.beginPath()
ctx.moveTo(150, 40000*-1);
ctx.lineTo(150, 40000);
ctx.closePath();
ctx.lineWidth = 1/lw;
ctx.moveTo(400000*-1, 75);
ctx.lineTo(40000, 75);
ctx.strokeStyle = "#8B8682";
ctx.stroke();
ctx.closePath();
//var xmax = 400000 - b
//var xmax1 = xmax/s
//var ymax = 400000*s
//var ymax1 = ymax + b
// The code below graphs the equation.
ctx.beginPath();
ctx.lineWidth = 1/lw;
ctx.moveTo(xnew, 180);
ctx.lineTo(180, ynew);
// ctx.lineTo(xmax, ymax)
// ctx.lineTo(xmax*-1, ymax*-1)
ctx.strokeStyle = "red";
ctx.stroke();
Here is the coding for the whole page:
As you can see the line, if drawn at all, doesn't become long enough, like it should. (linear lines are always infinite, so the line should be going across the WHOLE graph, not a small portion.)
var canwith=360
var canheight=360
// alert(window.innerWidth)
function doSolve() {
var s=''
var x1 = document.getElementById('x1').value
var y1 = document.getElementById('y1').value
var x2 = document.getElementById('x2').value
var y2 = document.getElementById('y2').value
var m
var b
var a
try {
if ((x2 - x1)==0) {
m='Undefined'
b='Undefined'
a=x1
} else {
m = (y2 - y1)/(x2 - x1)
b = (y2-x2*m)
a = (-b/m)
}
s += 'Coordinates are: ('
s += x1
s += ','
s += y1
s += '),('
s += x2
s += ','
s += y2
s += ')'
s += '<br>Slope:'
s += m
s +='<br>y intercept:'
s += b
s += '<br>x intercept:'
s += a
if (m=='undefined') {
s += '<br>Equation: x = ' + x1
} else {
s += '<br>Equation: y = '
if (m!=0) {
if (m!=1) {
s += m + 'x'
} else {
s += 'x'
}
}
if (b!=0) {
if (b>0) {
s += ' + ' + b
} else {
s += ' - ' + b*-1
}
}
}
document.getElementById('outputx').innerHTML=s
} catch (e) {alert(e.message)}
try {
var c=document.getElementById("graph_");
var ctx=c.getContext("2d");
graph_.style.backgroundColor="white";
var z0=Math.max(Math.abs(a),Math.abs(b));
var z=Math.round(z0);
var z1=Math.round(z);
var z2=z*2
// alert(z1);
// alert(z2);
var scale = 2*z/360;
var offsetX = 150;
var offsetY = 75
ctx.translate((-c.width /2 * scale) + offsetX,(-c.height / 2 * scale) + offsetY);
ctx.scale(scale,scale);
var lw = scale/2
var xnew = 360/2+360/2*a
var ynew = 360/2-360/2*b
alert(xnew);
alert(ynew);
ctx.lineWidth = 2/lw;
ctx.beginPath()
ctx.moveTo(150, 40000*-1);
ctx.lineTo(150, 40000);
ctx.closePath();
ctx.lineWidth = 1/lw;
ctx.moveTo(400000*-1, 75);
ctx.lineTo(40000, 75);
ctx.strokeStyle = "#8B8682";
ctx.stroke();
ctx.closePath();
var xmax = 400000 - b
var xmax1 = xmax/s
var ymax = 400000*s
var ymax1 = ymax + b
ctx.beginPath();
ctx.lineWidth = 1/lw;
ctx.moveTo(xnew, 180);
ctx.lineTo(180, ynew);
ctx.lineTo(xmax, ymax)
ctx.lineTo(xmax*-1, ymax*-1)
ctx.strokeStyle = "red";
ctx.stroke();
} catch (e) {alert(e.message)}
}
I couln't cope with your code, so I made my own implementation adjusting to your visual requirements, hope this fix the problem:
try {
var c = document.getElementById("graph_");
var ctx = c.getContext("2d");
graph_.style.backgroundColor="white";
var w = c.width;
var h = c.height;
var xAxisSize = 40;
var yAxisSize = 40;
var scaleFactorX = w / xAxisSize;
var scaleFactorY = -(h / yAxisSize);
var offsetX = -10;
var offsetY = -10;
ctx.scale(scaleFactorX, scaleFactorY);
ctx.translate((xAxisSize / 2) + offsetX, -((yAxisSize / 2) + offsetY));
ctx.lineWidth = 3 / scaleFactorX;
ctx.beginPath();
ctx.moveTo(-xAxisSize, 0);
ctx.lineTo( xAxisSize, 0);
ctx.strokeStyle = "#8B8682";
ctx.stroke();
ctx.closePath();
ctx.lineWidth = 3 / scaleFactorY;
ctx.beginPath();
ctx.moveTo(0, -yAxisSize);
ctx.lineTo(0, yAxisSize);
ctx.strokeStyle = "#8B8682";
ctx.stroke();
ctx.closePath();
ctx.lineWidth = 3 / scaleFactorY;
ctx.beginPath();
var xx1 = -xAxisSize - offsetX;
var yy1 = m * xx1 + b;
var xx2 = xAxisSize + offsetX;
var yy2 = m * xx2 + b;
ctx.moveTo(xx1, yy1);
ctx.lineTo(xx2,yy2);
ctx.strokeStyle = "red";
ctx.stroke();
ctx.closePath();
} catch (e) {
alert(e.message)
}