Plotar uma Função na Tela do Computador em HTML



1. Introdução
O conhecimento sobre funções e gráficos são indispensáveis para qualquer área de conhecimento científico e tecnológico, nas escolas  técnicas e nas faculdades as experiências nos laboratórios geralmente há uma função para ser plotada.
Este trabalho visa fornecer os conhecimentos básicos de como plotar um gráfico utilizando o HTML 5 e JavaScript, será plotado uma equação do 2º grau, para outros tipos de equações e só fazer as adaptações necessárias. Também poderá ser adaptado para outro tipo de linguagem, como o Java por exemplo, o importante é aprender o raciocínio.

Para uma dada função f(x) = y cuja domínio é [a,b] ∈ R  os valores de x ∈ [a,b] para que possam ser plotados na tela do computador ou em uma papel A4, na maioria das vezes é necessário uma escala. Da mesma forma que os desenhos técnicos tem uma escala de desenho, a escala dos eixos cartesiados também tem uma escala similar,  pois, o gráfico de uma função é na verdade um "desenho" matemático. A escala é uma razão entre a dimensão de "desenho" e a dimensão real, exemplo: escala 2:1 que dizer que o gráfico foi duplicado (escala = tamanho no desenho:tamanho real)

1.1. Módulo de Escala do eixo-x e eixo-y
É igual a razão entre o maior valor que vai no eixo dividido pelo comprimento do respectivo eixo no papel, arredondando para 1, 2, 5 ou 10 (multiplos de 10) para facilitar a leitura. Arredondado para 0.1, 0.2 ou 0.5. Para 1, 2 ou 5, para 10, 20 ou 50. Para 0.01, 002, 0.005, etc.
Exemplo:
Se o maior valor a ser plotado no eixo-x é 0,76  e o comprimento do eixo-x no papel é 120 mm, então:
modulo-x = 0,76/120 mm = 0,0065, isto quer dizer que 1mm no eixo-x tem 0,0065, para facilitar a leitura e as dimensões caberem no papel, pode-se arredondar 0,0065 para 0,01.
Portanto: modulo-x = 0,01, ou seja, 1mm no papel equivale a 0,01.
No computador a leitura do gráfico é feita automaticamente, porém, se o módulo da escala estiver conforme padronização acima mencionada, facilitará a sua leitura pelo usuário.

2. Sistema de Coordenadas Cartesiano

No sistema cartesiado para uma dada função f(x) = y, cuja domínio é [a,b] existe apenas um x ∈ [a,b] tal que f(x) = y.


Figura 1

3. Tela do Computador
A coordenada da tela é inversa do sistema cartesiano, as abscissa são idênticas.

Figura 2

3.1. Conversão para o Sistema de Coordenadas Cartesiano
Para plotar uma função na tela deve-se converter a tela  para o sistema de coordenadas cartesiano, para isso deve-se inverter o sinal do eixo-y da tela e transladar todos os pontos deste eixo para cima do eixo x da tela.

Translação Vertical
no Eixo Cartesiano
Simplesmente soma-se um valor a f(x) para o mesmo x.
f(x) → a + f(x)
a > 0 para cima ↑
a < 0 para baixo ↓

Translação Horizontal no Eixo Cartesiano
x → x + a
a > 0 deslocamento do gráfico para a esquerda ←, isto significa que o eixo-x se deslocou para a direita e o gráfico ficou parado, com isso,  o gráfico fica à esquerda.

a < 0 deslocamento do gráfico para a direita → , isto significa que o eixo-x se deslocou para à esquerda e o gráfico ficou parado, com isso,  o gráfico fica à direita.

3.2. Transformação para o Sistema Cartesiano
Deve-se fazer a translação e a mudança de escala do canvas.
O eixo-y da tela deve ser multiplicado por -1 e transladar os pontos da tela com o valor da sua altura do canvas.

4. Enquadramento
O gráfico da função deverá ser plotado em um sistema de coordenadas cartesianas, mas os valores de domínio e imagem da função não correspondem aos valores do sistema de coordenadas da tela gráfica, devemos então, fazer um ajuste dos valores de coordenadas da função com os valores na tela gráfica, da mesma forma que ocorre em desenho técnico. Para isso, é feito o enquadramento horizontal bem como o enquadramento vertical.

Exemplo de enquadramento horizontal:
eixo-x
0
100
200
300
400
500
600
700
800
900
1000
1100
1200
1300
1400
1500
1600
1700
1800
1900
2000
eixo-x'
0
10
20
30
40
50
60
70
80
90
100
110
120
130
140
150
160
170
180
190
200
Tabela1
eixo-x é a abscissa do sistema de coordenadas cartesiana da função f(x) = y.
eixo-x' é a abscissa da tela do computador.
A escala da tela é igual a 0,1.

Nota de inglês:
canvas (ˈkænvəs): s. 1. lona (tecido), 2. tela (para pintar).

Para fazermos o enquadramento devemos trabalhar com os valores extremos dos dois eixos tanto da tela como da função.
Conforme figura 1:
x ∈ [a,b], a,b ∈ R 
a ≤ x  ≤ b

Conforme figura 2:
  x'∈ [0,x'max], x'max ∈ R
0 ≤ x'  ≤ x'max

a
≤ x  ≤ b
0
≤ x'  ≤ x'max

Enquadramento Horizontal e Vertical:
A tela do computador tem um  tamanho limitado, na figura 3 abaixo foi criado um eixo auxiliar no mesmo sentido da tela, para cada ponto do eixo auxiliar corresponde apenas um ponto no eixo da tela, portanto é uma função do 1º grau. O eixo-x tanto da tela quanto do eixo auxiliar tem o mesmo sentido e direção.
O raciocínio é: em vez de trabalhar com as coordenadas da função dada, trabalha-se com as coordenadas da tela.

Dados:
Para uma função f(x) = ax² + bx + c, com a > 0.
Ponto mínimo da função: yi > 0
Ponto máximo da função: ys → +∞
ys * yi >0

Isto é, a > 0, com estes eixos a concavidade é voltada para baixo, no sentido do eixo-y da tela. yi > 0 e ys → +∞

eixo-x
a
 ... x ...
b
eixo-x'
0
... x' ...
x'max


Figura 3
A largura da tela corresponde a medida de 0 a x'max.
A altura da tela corresponde a medida de 0 a y'max.

Enquadramento Horizontal
Sabemos que a escala é uma constante.
(x - a) / (b - a) = (x' - 0)/(x'max - 0)
(x - a) / (b - a) = x' /x'max

x' = [(x - a) / (b - a)]*(x'max - 0)

x' = [x'max/(b - a)]*x -(a*xmax)/(b - a) é uma função do 1º grau


função do 1º grau: f(x) = qx + p
x' = [x'max/(b - a)]*x - (a*xmax)/(b - a)  (I)

q = [x'max/(b - a)]: coeficiente de x'
p = -(a*xmax)/(b - a): termo constante

Valores de x:
Basta isolar o termo x da equação anterior.
(x - a) / (b - a) = (x' /x'max )

x = [(b-a)]*x'/x'max + a (II)

Obs:

a, b e x'max são dados e os valores de x' são escolhidos (variam de 0 até x'max), dessa forma é só achar os valores de x que correspondem as abscissas do eixo-x e substituí-los na função a ser plotada para achar f(x) = x', repare isso na figura 3.

Tabelamento da Função Inicial
Devemos escolher a quantidade de pontos do eixo-x' (tela), escolhe-se o valor inicial e o final que corresponderão ao domínio da função, basta então escolher um certo números de valores dentro desse conjunto e substituir na função do 1º grau já desenvolvida, o resultado deve ser inserido na função a ser plotada.
Exemplo:
Dada uma função f(x) = x² +2 de domínio [0,100] a ser plotada na tela podemos tabelar os valores de f(x):
Dados o domínio: a =0 e  b = 100
Escolha: x'max = 1000, podemos fazer um loop e variar x' de 0 a 1000 incrementando 1 (0, 1, 2, 3, 4, ...,1000) pois a menor unidade ou medida da tela é 1 que corresponde a 1 (um) pixel.
x' = 0, x' = 1, x' = 2, ...
x = [(b-a)]*x'/x'max + a (II)
f(x) = x² + 2
xo = [(b - a)*x'o/x'max] + a = [(100*0)/1000] + 2= 2
f(xo) = 2² + 2  = 6
x1 = [(b - a)*x'1/x'max] + a = [100*1/1000] + 2 = 2,1 f(x1) = 2,1² + 2 = 6,41
...
...
Obs: substitui x' na fórmula e acha x, substitui x na função e acha f(x).

Portanto já temos:
1) O domínio da função que é dado junto com a função a ser plotada.
Os valores do domínio da função dada são os números a serem lidos no gráfico no eixo-x' (tela).
2) As abscissas da tela são escolhidas.
Os valores das abscissas da tela são as abscissas dos pontos da tela que representam os valores do domínio da função dada.
3) Os valores de x da função dada foram calculados na função de 1º grau que foi desenvolvida, fórmula (II).
Esses valaores são calculados conforme tabela acima.
4) Os valores de f(x) são achados substituindo os valores de x na fórmula da função dada, cuja resultado são as abscissas da tela, x'.

Só ficou faltando as ordenadas do eixo-y' (tela) para plotar as função dada. Uma vez que as ordenas no eixo-y' da tela tem abscissa 0 (zero) e as abscissas no eixo-x' (tela) tem ordenadas igual a (zero).

5. Achar os pontos máximo e minimo da função dada f(x).
Com o tabelamento da função é só fazer uma rotina para achar o maior valor e o menor valor.
Para x' variando de 0 até x'max faça
se ys < y(x') então ys ← y(x'), ou seja, recebe o maior.
se yi > y(x') então yi ← y(x'), ou seja, recebe o menor.

Revisão
Primeiramente deve-se interpretar a função e saber que tipo de curva é o gráfico e saber sua concavidade, se é para cima ou para baixo.  Recordando os estudos vejamos um exemplo de uma equação do 2º grau, f(x) = ax² - bx +c:
Plano cartesiano: f(x) = ax² - bx +c


Para o gráfico do quadrante I no plano cartesiano:
Ponto mínimo da função: yi > 0
Ponto máximo da função: ys → +∞
ys * yi > 0

Para o gráfico do quadrante II no plano cartesiano:
Ponto mínimo da função: ys > 0
Ponto máximo da função: yi → -∞
ys * yi < 0

Para o gráfico do quadrante III no plano cartesiano:
Ponto mínimo da função: ys < 0
Ponto máximo da função: yi → -∞
ys * yi > 0

Para o gráfico do quadrante IV no plano cartesiano:
Ponto mínimo da função: yi < 0
Ponto máximo da função: ys → +∞
ys * yi < 0

Plano da Tela do Computador: f(x) = ax² - bx +c
O eixoY é crescente de cima para baixo conforme figura a seguir

Para o gráfico do quadrante I no plano cartesiano:
Ponto mínimo da função: yi < 0
Ponto máximo da função: ys → -∞
ys * yi > 0

Para o gráfico do quadrante II no plano cartesiano:
Ponto mínimo da função: ys < 0
Ponto máximo da função: yi → +∞
ys * yi < 0

Para o gráfico do quadrante III no plano cartesiano:
Ponto mínimo da função: yi > 0
Ponto máximo da função: ys → +∞
ys * yi > 0

Para o gráfico do quadrante IV no plano cartesiano:
Ponto mínimo da função: ys > 0
Ponto máximo da função: yi → -∞
ys * yi < 0

6. Enquadramento Vertical
O raciocínio é o mesmo do enquadamento horizontal, os valores calculados da função já tabelado deverão ser enquadrados em um eixo vertical da tela.
A relação dos valores da função tabelada (eixo-y) com os pontos da tela (eixo-y') são uma função de 1º grau.

eixo-y
eixo-y'
ys
0
...
y
...
...
y'
...
yi
y'max

Observe na figura 3 que o eixo-y da função aumenta para baixo e o eixo-y' da tela aumenta também para baixo. Na tabela 1 pode-se observar uma relação de proporção entre as duas ordenadas:

(y - yi)/(ys - yi) = (y'- 0)/(y'max - 0)
(y - yi)/(ys - yi) = y'/y'max
y' = [(y - yi)/(ys - yi)]*y'maxy'
y' = [(y - yi)/(ys - yi)]*y'max (III-A)

Função do 1º grau: f(x) = qx + p
y' = [y'max/(ys - yi)]*y - [yi*ymax/(ys-yi)]  (III-B)
q = [y'max/(ys - yi)]
p = - [yi*ymax/(ys-yi)]

Observe que:
f(x) = x': foi escolhido um intervalo e um incremento conforme tabelamento da função inicial.
ys e yi: foram achado conforme rotina padrão de programação (maior e menor em uma lista).
y'max: deve ser escolhido conforme altura da tela.
y': o único dado que estava faltanto para plotar a função.

7. Plotar eixo e gráfico
Plotagem dos eixos na tela.

Da mesma forma que já foi visto:
Conforme figura 1:
x ∈ [a,b], a,b ∈ R 
a ≤ x  ≤ b

Conforme figura 2:
  x'∈ [0,x'max], x'max ∈ R
0 ≤ x'  ≤ x'max

7.1. plotagem do eixo-x
O gráfico de uma constante é uma reta. Todas as abscissas do eixo-x tem ordenadas igual a zero.


Se ys*yi < 0  o gráfico corta o eixo-x em um ponto com ordedanda y = 0
Para  y = 0,  a fórmula (III-B) fica: 
y' = - [yi*ymax/(ys-yi)]   = constante  (ordenada da origem do eixo-x', fazer o arredondamento)
Para x' = 0 até x'max faça Px(x',y')

7.2. plotagem do eixo-y
O gráfico de uma constante é uma reta. Todas as ordenadas do eixo-y tem abscissa igual a zero.
Se a*b < 0  o gráfico corta o eixo-y em um ponto com abscissa x = 0
Substitua  x = 0 na fórmula (I):  x' = [x'max/(b - a)]*x -(a*xmax)/(b - a)

x' = -(a*xmax)/(b - a) = constante (abscissa da origem do eixo-y', fazer o arredondamento)
Para y' = 0 até y'max faça Px(x',y')

8. Plotagem do gráfico
8.1. Achar os valores de x
Para x' varianado de 0 até x'max faça:
x = [(b - a)/x'max] * x' + a (II)

Obs:
x' são pontos da tela a ser escolhidos, quanto mais pontos, mais perfeita será a curva.
a, b: domínio da função, é dado.
x'max: é o valor máximo da abscissa da tela, é escolhido, deve ser menor que a largura do canvas.

8.2. Achar os valores de y
Substituir os valores de x achado no item 8.1 na função dada f(x) = y.

8.3. Achar os valores de y'
Substituir os valores de f(x) = y achados no item 8.2 na fórmula (III-A):

y' = [(y[] - yi)/(ys - yi)]*y'max

Portanto, pontos do gráficos são:
(x',y')

9. Prática
Após a teoria vamos para a prática, o gráfico será plotado utilizando HTML 5 e JavaScript, o código é bem simples, outras linguagens de programação como o java tem mais recursos, porém o HTML e o JavaScript é mais apropriado para ser executado diretamente pelo Browser.
As etapas de tabelamento, achar a função máxima e mínima, plotar os eixos e plotar o gráfico propriamente tido foram feitos todas essas etapas em uma só função, a função faz(), no Java por exemplo é mais conveniente cada etapa ser feita em funções separadas, uma função em java consegue enchergar uma  variável do tipo pública declarada fora da função.

Será plotado uma função de 2º grau, f(x) = ax² + bx + c.

9.1. Inserir o elemento <canvas>
O gráfico será plotado no eixo cartesiano, portando o eixo-y auxiliar utilizado anteriormente dever ser multipliado por -1, ou seja, escala de -1.
Os pontos da canvas deve ser transladado com a medida da altura do próprio canvas.

O código até aqui fica assim então:

<canvas id="idcanvas" width="400" height="450" style="border:1px solid #000000;"></canvas>
<script>
var canvas = document.getElementById("idcanvas");
var ctx = canvas.getContext("2d");

ctx.translate(0, 450);
ctx.scale(1, -1);
...

9.2. Tabelar a função
Será plotado a função 2x² + 4x - 1000



ordenada do eixo-x: y' = - [yi*ymax/(ys-yi)]   = constante
abscissa do eixo-y: x' = -(a*xmax)/(b - a) = constante
x'∈ [0,x'max], x'max ∈ R
0 ≤ x'  ≤ x'max
x = [(b - a)/x'max] * x' + a
Substituir os valores de f(x) = y em y' = [(y - yi)/(ys - yi)]*y'max


Criar a função faz(), onde:
a e b são os domínios da função a ser plotada.
c são os pontos do eixo-x' (tela). O arredondamento é necessário porque as unidades em pixel são em números inteiros.
f corresponde a origem do eixo-y. O arredondamento é necessário porque as unidades em pixel são em números inteiros.
d corresponde a origem do eixo-x. O arredondamento é necessário porque as unidades em pixel são em números inteiros.
(d,f) = (0,0)
d∈ [0,x'max]
f∈ [0,y'max]

Obs: o gráfico será plotado utilizando o método moveTo() e lineTo(), ou seja, utilizando retas, se for utilizar pontos ou pixel em outra linguagem de programação é so fazer as adaptações necessárias.
e são as demais ordenadas do gráfico a ser plotado.
???y[] são as ordenadas da função a ser plotada. (c,y[])
ys é a ordenada máxima da função.
yi é a ordenada mínima da função.

Código:
//tabelar
function faz() {
   var y = new Array();
   var ys = new Array();
   var yi = new Array();
   var d, e, f;
   var a=-100; //escolhido
   var b=100; //escolhido

   for(var c=0; c<=350; c++){
      x=a+(b-a)*c/350;          //x = [(b - a)/x'max] * x' + a
      y[c]= 2*x*x + 4*x - 1000;
      //document.write(y[c] + "<br>");
   }

9.3. Maior Menor
Rotina padrão usada para achar o maior e o memor valor em uma array, em JavaScript há uma função específica para isso, porém o intuito aqui é mostrar a forma mais geral.
A linha //document.write(yi + "<br>" + ys) é uma linha de teste, no código aprecerá várias vezes para testar os valores das variáveis.

Código:
 //MaiorMenor
   var ys = y[0];
   var yi = y[0];

   for(var c=0;c<=350;c++){
      if (y[c]>ys){
         (ys=y[c]);
      }
      else if (y[c]<yi) {
         (yi=y[c]);
      }
   }
   //document.write(yi + "<br>" + ys);

9.4. Plotar os Eixos
Se ys*yi<0 o eixo-x da função existe, d é a ordenada do eixo-x' da tela, ou seja, corresponde ao ponto 0 (zero) da ordenada da função a ser plotada.
Se a*b<0 o eixo-y da função existe, c é a abscissa do eixo-y' da tela, ou seja, corresponde ao ponto 0 (zero) da abscissa da função a ser plotada.
Portanto o eixo de origem do gráfico da tela é o ponto (c,d).

//plotar eixos
   ctx.beginPath();
   //ctx.translade(0, 450);
   //ctx.scale(1, -1); 
   if (ys*yi<0){
      d=Math.round((-400*yi)/(ys-yi)); //ordenada do eixo-x: y' = - [yi*ymax/(ys-yi)] é uma  constante
                  ctx.strokeStyle = '#000';
                  ctx.beginPath();
                  ctx.lineWidth = 2;
                  ctx.moveTo(0,d);//
                  ctx.lineTo(350,d);
                  ctx.lineTo(340,d-10);//seta do eixoX
                  ctx.moveTo(350,d);//seta do eixoX
                  ctx.lineTo(340,d+10);//seta do eixoX

                  ctx.stroke();
                  ctx.closePath(); 
   }
   ctx.beginPath(); 
   if (a*b<0){
       c=Math.round(-a*350/(b-a));// abscissa do eixo-y: x' = -(a*xmax)/(b - a) é uma constante
                  ctx.strokeStyle = '#000';
                  ctx.beginPath();
                  ctx.lineWidth = 2;
                  ctx.moveTo(c,0);
                  ctx.lineTo(c,400);
                  ctx.lineTo(c-10,390);//seta do eixoY
                  ctx.moveTo(c,400);//seta do eixoY
                  ctx.lineTo(c+10,390);//seta do eixoY

                  ctx.stroke();
                  ctx.closePath();  
   }
//document.write(d + "<br>" + c);

9.5. Plotagem do gráfico da Função na Tela
(0,f) é o primeiro ponto do gráfico, precisa-se desse ponto para desenhar uma reta, pois a curva será feita com 350 retas, caso utilize pontos para desenhar a curva em outra linguagem de programação, esta etapa é desnecessária.
e = Math.round(((y[c]-yi)/(ys-yi))*400), f(x) = y, vide item 8.3.

O evento window.onload=faz executa a função faz() automaticamente, porém será usado o botão abaixo para executar a função faz().
Botão do HTML de execução da função faz(): <button onclick="faz()">Clique aqui</button.
O arredondamento de f é necessário porque as unidades em pixel são em números inteiros.

Código do gráfico
 //PlotarGrafico
   ctx.strokeStyle = '#000';
   ctx.beginPath();
   ctx.lineWidth = 2;

   f = Math.round(((y[0]-yi)/(ys-yi))*400); // ordenada do primeiro ponto do gráfico
//document.write(f);
 
   ctx.beginPath();
   //ctx.translate(0, 450);
   //ctx.scale(1, -1);
   ctx.moveTo(0,f);    //primeiro ponto a ser plotado
//document.write(f);

// demais pontos
        for(var c=0;c<=350;c++){ 
           e = Math.round(((y[c]-yi)/(ys-yi))*400); 
//document.write(e + "<br>");

            ctx.lineWidth = 1;

            ctx.lineTo(c,e);
         }
             ctx.stroke();
             ctx.closePath();
//textos
ctx.scale(1,-1); //para corrigir o texto
ctx.font="20px Georgia";
ctx.fillText("(0,0)",180,-30);
ctx.fillText("eixo-y",180,-400);
ctx.fillText("eixo-x",330,-40);
ctx.fillText("f(x)=2*x*x+4*x-1000",180,-200);
}

//window.onload=faz;
</script> 
<button onclick="faz()">Clique aqui</button>

Código completo:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<canvas id="idcanvas" width="400" height="450" style="border:1px solid #000000;"></canvas>
<script>
//plotar eixos
var canvas = document.getElementById("idcanvas");
var ctx = canvas.getContext("2d");

ctx.translate(0, 450);
ctx.scale(1, -1);


//tabelar

function faz() {
   var y = new Array();
   var ys = new Array();
   var yi = new Array();
   var a=-100;
   var b=100;
   var d, e, f;

   for(var c=0; c<=350; c++){
      x=a+(b-a)*c/350;
      y[c]= 2*x*x + 4*x - 1000;
      //document.write(y[c] + "<br>");
   }

//MaiorMenor
   var ys = y[0];
   var yi = y[0];

   for(var c=0;c<=350;c++){
      if (y[c]>ys){
         (ys=y[c]);
      }
      else if (y[c]<yi) {
         (yi=y[c]);
      }
   }
   //document.write(yi + "<br>" + ys);

//plotar eixos
   ctx.beginPath();
   //ctx.translate(0, 450);
   //ctx.scale(1, -1); 
   if (ys*yi<0){
      d=Math.round((-400*yi)/(ys-yi)); //abscissas do gráfico da tela
                  ctx.strokeStyle = '#000';
                  ctx.beginPath();
                  ctx.lineWidth = 2;
                  ctx.moveTo(0,d);//
                  ctx.lineTo(350,d);
                  ctx.lineTo(340,d-10);//seta do eixoX
                  ctx.moveTo(350,d);//seta do eixoX
                  ctx.lineTo(340,d+10);//seta do eixoX

                  ctx.stroke();
                  ctx.closePath(); 
   }
   ctx.beginPath(); 
   if (a*b<0){
       c=Math.round(-a*350/(b-a));//ordenada do grafico da tela
                  ctx.strokeStyle = '#000';
                  ctx.beginPath();
                  ctx.lineWidth = 2;
                  ctx.moveTo(c,0);
                  ctx.lineTo(c,400);
                  ctx.lineTo(c-10,390);//seta do eixoY
                  ctx.moveTo(c,400);//seta do eixoY
                  ctx.lineTo(c+10,390);//seta do eixoY

                  ctx.stroke();
                  ctx.closePath();  
   }
//document.write(d + "<br>" + c);
//PlotarGrafico
   ctx.strokeStyle = '#000';
   ctx.beginPath();
   ctx.lineWidth = 2;

   f = Math.round(((y[0]-yi)/(ys-yi))*400); // ordenada do primeiro ponto do gráfico
//document.write(f);
 
   ctx.beginPath();
   //ctx.translate(0, 450);
   //ctx.scale(1, -1);
   ctx.moveTo(0,f);    //primeiro ponto a ser plotado
//document.write(f);

// demais pontos
        for(var c=0;c<=350;c++){ 
           e = Math.round(((y[c]-yi)/(ys-yi))*400);
//document.write(e + "<br>");

            ctx.lineWidth = 1;

            ctx.lineTo(c,e);
         }
             ctx.stroke();
             ctx.closePath();
//textos
ctx.scale(1,-1); //para corrigir o texto
ctx.font="20px Georgia";
ctx.fillText("(0,0)",180,-30);
ctx.fillText("eixo-y",180,-400);
ctx.fillText("eixo-x",330,-40);
ctx.fillText("f(x)=2*x*x+4*x-1000",180,-200);
}
//window.onload=tabela;
//window.onload=maiorMenor;
//window.onload=plotarEixos;
//window.onload=faz;
</script> 
<button onclick="faz()">Try it</button>
</body>
</html>




Obs:
O arredondamento é necessário porque as unidades em pixel são em números inteiros.
Foram desenhados também as setas dos eixos e inserido textos no gráfico.