graph plotter for schoolchildren

44 views
Skip to first unread message

geddes...@gmail.com

unread,
Mar 26, 2021, 4:12:51 PMMar 26
to 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:

<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.11/paper-full.min.js"></script>
<input type="number" id="input_xWidth" value=14><br>
<input type="number" id="input_yWidth" value=4><br>
<input type="text" id="eqn" value='sin(x)'><br>
<button onclick="drawGrid()">draw grid</button>
<button onclick="exportSVG()">export</button> <br><br> <canvas id="canvas_1"></canvas><br>

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("input_xWidth").value;

    var yWidth = document.getElementById("input_yWidth").value;


    var z;

    var zz;


    //clear the canvas

    graphScope.project.activeLayer.removeChildren()


    //draw minor gridlines

    for (z = 0; z < xWidth; z++) {

        for (zz = 1; zz < 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 < yWidth; z++) {

        for (zz = 1; zz < 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 <= 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 <= 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("eqn").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 < 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 = "custom.svg"

    var url = "data:image/svg+xml;utf8," + encodeURIComponent(graphScope.project.exportSVG({

        asString: true

    }));

    var link = document.createElement("a");

    link.download = fileName;

    link.href = url;

    link.click();

}


Juro Dobrik

unread,
Apr 14, 2021, 11:43:13 AMApr 14
to pap...@googlegroups.com
You are going over loop with 1000 points per z, and that takes long time...



pi 26. 3. 2021 o 21:12 geddes...@gmail.com <geddes...@gmail.com> napísal(a):
--
You received this message because you are subscribed to the Google Groups "Paper.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to paperjs+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/paperjs/0546ead8-c623-4da4-8df5-2ae27b33f047n%40googlegroups.com.

asensi...@gmail.com

unread,
May 25, 2021, 2:01:11 PMMay 25
to Paper.js
Hi,

You could:
- reduce the number of point of your path (as mentioned in the previous comment)
- get rid of the `intersect` boolean operation (which can be costly for complex paths) on your path and use a clip mask instead as follow:
// var NewPath = graphPath.intersect(GraphBoundary, {
//     trace: false
// });
// NewPath.strokeColor = new graphScope.Color(0.1, 0.1, 0.1);
// graphPath.remove();
graphPath.strokeColor = new graphScope.Color(0.1, 0.1, 0.1);
const clipGroup = new graphScope.Group(GraphBoundary, graphPath);
clipGroup.clipped = true;

Reply all
Reply to author
Forward
0 new messages