jsxgraph

JSXGraph: Is there a more robust metric for majorHeight?


I recently discovered how flexibly one can actually draw axes. However, I struggle with grid lines for the ticks. I can calculate the required majorHeight and set it for any specific combination of canvas size and axis lengths.

But when the canvas is squashed, e.g. due to a too narrow browser window, the grid lines' length remains constant and they become too long. In the example below (sorry, I do not know a way to provide an MWE where the canvas can actually be squashed...), the y-axis' lines should run from 0 to 5 along the x-axis. But in a narrower window, these lines extend beyond the x-value of 5.

MWE: Sine Function Parameters

var brd = JXG.JSXGraph.initBoard('BOARDID0', {
    boundingbox: [-0.5, 3, 10, -3], axis: false });

var xAxis = brd.create('axis', [ [0,0],[5.4,0] ], {
    straightFirst: false, straightLast: false,
    withLabel: true, name: 't (s)',
    label: {position: 'rt', offset: [0, 15], anchorX: 'right' },
    ticks: {ticksDistance: 1, majorHeight: 267, tickEndings: [1,1],
        insertTicks: false, minorTicks: 1, minorHeight: 267,
        label: {anchorX: 'middle', anchorY: 'top', offset: [0,-3] } }
    });
var yAxis = brd.create('axis', [ [0,-2.4],[0,2.4] ], {
    straightFirst: false, straightLast: false,
    withLabel: true, name: 'y (m)',
    label: {position: 'rt', offset: [12, -3], anchorX: 'left' },
    ticks: {ticksDistance: 1, majorHeight:762, drawZero: true,
        insertTicks: false, minorTicks: 1, minorHeight: 762,
        label: {anchorX: 'right', anchorY: 'middle', offset: [-3,0] } }
    }); 

Is there maybe a better, more robust (and maybe simpler) way to fix the majorHeight?


Solution

  • In the example, majorHeight and minorHeight are given as constant pixel values. However, it is also possible to supply these values as functions. One possible solution is to supply the size of the ticks as a function in user coordinates and convert these into pixel values using board.unitX and board.unitY. For some reason, the user coordinates have to multiplied by two. Here is an example:

    var xAxis = board.create('axis', [ [0,0],[5.4,0] ], {
        straightFirst: false, straightLast: false,
        withLabel: true, name: 't (s)', /* name: '$$x\\;\\mathrm{(m)}$$', */
        label: {position: 'rt', offset: [0, 15], anchorX: 'right', parse: false, fontSize: 12 },
        ticks: {ticksDistance: 1, 
            majorHeight: ()=>4*board.unitY, 
            minorHeight: ()=>4*board.unitY,
            tickEndings: [1,1],
            insertTicks: false, minorTicks: 1, 
            label: {anchorX: 'middle', anchorY: 'top', offset: [0,-3] } }
        });
    var yAxis = board.create('axis', [ [0,-2.4],[0,2.4] ], {
        straightFirst: false, straightLast: false,
        withLabel: true, name: 'y (m)', /* name: '$$x\\;\\mathrm{(m)}$$', */
        label: {position: 'rt', offset: [12, -3], anchorX: 'left', parse: false, fontSize: 12 },
        ticks: {ticksDistance: 1, 
            majorHeight: ()=>10*board.unitX,
            minorHeight: ()=>10*board.unitX,
            drawZero: true,
            insertTicks: false, minorTicks: 1, 
            label: {anchorX: 'right', anchorY: 'middle', offset: [-3,0] } }
        }); 
    

    At https://jsfiddle.net/hrt56j1e/1/ there is a working example using v1.4.3.