Search code examples
moodlejsxgraph

JSXGraph: Multiple boards with Moodle's Formulas and Stack


Sometimes it is handy to be able to control the placement of multiple JSXGraph boards on the html page, like on https://jsxgraph.org/wiki/index.php?title=Sine.

I know that it is possible to include more than one board in a Formulas question in Moodle, as described here: https://github.com/jsxgraph/moodleformulas_jsxgraph/blob/master/README.md#insert-more-than-one-board-into-a-question

My question is: Is it possible to gain control over the placement of boards in a Formulas question? And/or is that possible in a STACK question? – Thanks!


Solution

  • With STACK, it is possible to include more than one board into a question. For each JSXGraph block, STACK generates a div with an id stored in the divid variable. The divs for the boards then replace the JSXGraph blocks in the question text.

    Board interaction

    If you want the boards to interact with each other, you need to write the JavaScript code for the boards in a single JSXGraph block (the JavaScript code in a block is encapsulated). To do so, you should first place an empty JSXGraph block in the question text which will generate the first div with an id of the pattern "stack-jsxgraph-1". Then, you add a second block where you put in the code for the two boards. Since the naming for the divids is basically just counting up a number, you can access the divid for the first board with regular expressions in JavaScript.

    Board placement

    In order to control the placement, you can use some CSS and HTML. For example you can wrap two JSXGraph blocks in a div and make this div a flexbox with display: flex. The two boards will then align horizontally. You can also use a grid layout.

    Example Code

    The code for the question text could look like this:

    <!-- Wrapper div flexbox -->
    <div style="display: flex;">
    <!-- Empty JSXGraph block for the first board-->
    [[ jsxgraph width="200px" height="200px"]] [[/ jsxgraph ]]
    
    <!-- JSXGraph block for the second board-->
    [[ jsxgraph width="200px" height="200px"]]
    /* divid variables */
    const divid1 = divid.replace(/[0-9]+/g,divid.match(/[0-9]+/g)-1)
    const divid2 = divid;
    console.log(divid1, divid2);
    /* init boards */
    const board1 = JXG.JSXGraph.initBoard(divid1,{ boundingbox: [-5, 5, 5, -5], axis: true });
    const board2 = JXG.JSXGraph.initBoard(divid2,{ boundingbox: [-5, 5, 5, -5], axis: true });
    [[/ jsxgraph ]]
    </div>
    

    The STACK question then shows two boards: stack question with two jsxgraph boards

    This code creates two JSXGraph boards inside the second JSXGraph block that can interact with each other. The placement is done with a flexbox wrapper-div. I think this should also work for Formulas similarly. I hope this answers your question.