A JavaScript graph plotter for schoolchildren using paper.js I have begun coding a simple graph plotter for my schoolchildren using JavaScript. I have used the paper.js library as I would like to be able to export the graphs as svg files.
I am only a beginner to all this (just a humble maths teacher) so I would hugely welcome any thoughts you may have. The code does not run particularly quickly so I would be particularly interested in any improvements to performance.
Many thanks and best wishes.
HTML:
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.11/paper-full.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/mathjs/9.3.0/math.min.js&quot;&gt;&lt;/script&gt;

&lt;input type=&quot;number&quot; id=&quot;input_xWidth&quot; value=14&gt;&lt;br&gt;
&lt;input type=&quot;number&quot; id=&quot;input_yWidth&quot; value=4&gt;&lt;br&gt;
&lt;input type=&quot;text&quot; id=&quot;eqn&quot; value='sin(x)'&gt;&lt;br&gt;

&lt;button onclick=&quot;drawGrid()&quot;&gt;draw grid&lt;/button&gt;
&lt;button onclick=&quot;exportSVG()&quot;&gt;export&lt;/button&gt;

&lt;br&gt;&lt;br&gt;

&lt;canvas id=&quot;canvas_1&quot;&gt;&lt;/canvas&gt;&lt;br&gt;

JavaScript:
var graphScope = new paper.PaperScope();
var canvas_1 = document.getElementById('canvas_1');
graphScope.setup(canvas_1);
graphScope.activate();

const scale = 10;

function drawGrid() {

  var xWidth = document.getElementById(&quot;input_xWidth&quot;).value;
  var yWidth = document.getElementById(&quot;input_yWidth&quot;).value;

  var z;
  var zz;

  //clear the canvas
  graphScope.project.activeLayer.removeChildren()

  //draw minor gridlines
  for (z = 0; z &lt; xWidth; z++) {
    for (zz = 1; zz &lt; 5; zz++) {
      var myPath = new graphScope.Path();
      myPath.strokeColor = new graphScope.Color(0.9, 0.9, 0.9);
      myPath.add(new graphScope.Point(z * scale + (scale / 5) * zz, -(0)));
      myPath.add(new graphScope.Point(z * scale + (scale / 5) * zz, -(yWidth * scale)));
    }
  }

  for (z = 0; z &lt; yWidth; z++) {
    for (zz = 1; zz &lt; 5; zz++) {
      var myPath = new graphScope.Path();
      myPath.strokeColor = new graphScope.Color(0.9, 0.9, 0.9);
      myPath.add(new graphScope.Point(0, -(z * scale + (scale / 5) * zz)));
      myPath.add(new graphScope.Point(xWidth * scale, -(z * scale + (scale / 5) * zz)));
    }
  }

  //draw major gridlines
  for (z = 0; z &lt;= xWidth; z++) {
    var myPath = new graphScope.Path();
    myPath.strokeColor = new graphScope.Color(0.5, 0.5, 0.5);
    myPath.add(new graphScope.Point(z * scale, -(0)));
    myPath.add(new graphScope.Point(z * scale, -(yWidth * scale)));
  }

  for (z = 0; z &lt;= yWidth; z++) {
    var myPath = new graphScope.Path();
    myPath.strokeColor = new graphScope.Color(0.5, 0.5, 0.5);
    myPath.add(new graphScope.Point(0, -(z * scale)));
    myPath.add(new graphScope.Point(xWidth * scale, -(z * scale)));
  }

  // parse equation from input box
  const node2 = math.parse(document.getElementById(&quot;eqn&quot;).value)
  const code2 = node2.compile()
  let scope = {
    x: 3,
  }


  // trim graph to grid
  var rectangle = new graphScope.Rectangle(new graphScope.Point(0, 0), new graphScope.Point(xWidth * scale, -yWidth * scale));
  var GraphBoundary = new graphScope.Path.Rectangle(rectangle);
  var graphPath = new graphScope.Path();
  for (z = 0; z &lt; xWidth; z += 0.001) {
    scope.x = z
    graphPath.add(new graphScope.Point(z * scale, -(20 + scale * code2.evaluate(scope))));
  }
  var NewPath = graphPath.intersect(GraphBoundary, {
    trace: false
  })
  NewPath.strokeColor = new graphScope.Color(0.1, 0.1, 0.1);
  graphPath.remove();

  //fit page to canvas bounds
  graphScope.project.activeLayer.fitBounds(graphScope.view.bounds);
}

function exportSVG() {
  var fileName = &quot;custom.svg&quot;
  var url = &quot;data:image/svg+xml;utf8,&quot; + encodeURIComponent(graphScope.project.exportSVG({
    asString: true
  }));
  var link = document.createElement(&quot;a&quot;);
  link.download = fileName;
  link.href = url;
  link.click();
}
I'm not familiar with Paper so can't say anything about that. And I won't say much about the HTML, as it's obviously just a functional placeholder, except two points:

Use double quotes &quot; consistently on all attributes.
Don't use on... attributes. Assign event listeners in the script using addEventListener.

Regarding the script:

Use let/const instead of var.
Declare the variable in loops separately in the for statement using let (e.g. don't reuse the same declared variable in all loops).
Use better variable names. I have no idea what z, zz, node2, code2, etc. mean. (Also make sure all variable names start with a lower case letter.)
Don't repeatedly create the same colors in the loops. Create them once outside the loop.