Home | Math Display Experiments | JSXGraph Coding Summary

Page by Murray Bourne, IntMath.com. Last updated: 21 Feb 2016# JSXGraph Coding Summary

Last updated: 21 February 2016.

Here are some things I couldn't find easily in the JSXGraph documentation, or are recent changes to how things work, or things I keep forgetting how to do.

I wrote it as a summary for myself, but I hope it's useful for anyone else who is trying to get JSXGraph to do what you want it to.

See also: JSXGraph axes, ticks and grids, which has several examples of one of the trickiest things to get your head around.

## Turn off navigation and copyright notice

var board = JXG.JSXGraph.initBoard('jxgbox0', { boundingbox:[-15,5,15,-5], axis:true, showCopyright:false, showNavigation:false });

## Turn off pan ability

By default, when you shift-drag on a board, the graph moves in the direction of the drag (this is called "panning").

Sometimes we don't want that, and using `pan: {enabled:false}`

will take care of it. Other boards on this page can be panned using shift-drag.

(This example also demonstrates how to construct a Lagrange Polynomial. Dragging any of the points will change the curve passing through those points.)

var board = JXG.JSXGraph.initBoard('jxgbox1', {axis:true, pan: {enabled:false}} ); var p = []; var q = []; p[0] = board.create('point', [-1,2]); p[1] = board.create('point', [3,-1]); p[2] = board.create('point', [-3,-3]); var f = JXG.Math.Numerics.lagrangePolynomial(p); var graph = board.create('functiongraph', [f]);

## Remove slider ticks and axis highlights

Random ticks on sliders can be removed with the following, before initializing the board:

JXG.Options.slider.ticks.majorHeight = 0;

Ticks label highlight and axis highlight can be removed with the following, before initializing the board: (This applies to all subsequent boards on the page.)

JXG.Options.axis.ticks.label.highlight = false; JXG.Options.axis.highlight = false;

## Create parametric curve

Create parametric curves in JSXGraph as follows.

var board = JXG.JSXGraph.initBoard('jxgbox3',{axis:true}); function x(t) {return 3*Math.sin(t); }; function y(t) {return 3*Math.cos(3*t); }; board.create('curve', [ function(t) { return x(t);}, function(t) { return y(t);} ]);

## Remove all objects from board

var board = JXG.JSXGraph.initBoard('jxgbox4'); for(el in board.objects) { board.removeObject(board.objects[el]); }

## Change bounding box dynamically

Sometimes we want to change the bounding box after some event has occurred. You can do it with `setBoundingBox`

as follows.

The default bounding box is [-5,5,5,-5]. This code changes it to [-1,10,3,-7], while the button changes it even more.

var board = JXG.JSXGraph.initBoard('jxgbox5',{ axis:true, showCopyright:false, showNavigation:false }); var p = board.create('point', [-2, 3]); board.setBoundingBox([-1,10,3,-7]); $('#chngBb').click(function(){ start = -5 + 5*Math.random(); end = 5*Math.random(); board.setBoundingBox([start, end, end, start]); // board.update(); });

## Change domain of curve dynamically

The default behavior for graphs of continuous functions is they will extend across the whole board width.

Sometimes we want to change the upper or lower limits of the independent variable (the domain), either on initial plot, or after some event has occurred. You can do it by adding extra parameters as follows.

Click the button to change the domain definition. (I'm using jQuery to drive the button event.)

var board = JXG.JSXGraph.initBoard('jxgbox6',{ axis:true, showCopyright:false, showNavigation:false }); var start_x = -1; var end_x = 3; $('#llim').text(start_x.toFixed(2)); $('#ulim').text(end_x.toFixed(2)); board.create('functiongraph', [ function(x) { return x*Math.sin(2*x); }, function(){ return start_x;}, function(){ return end_x;} ]); $('#changeDomain').click(function(){ start_x = -5 + 10*Math.random(); end_x = -5 + 10*Math.random(); $('#llim').text(start_x.toFixed(2)); $('#ulim').text(end_x.toFixed(2)); board.update(); });

Current domain: < *x* <

## Aspect ratio

When you create a circle, you want it to look like one. The command `keepaspectratio:true`

ensures the axes have the same scale.

var board = JXG.JSXGraph.initBoard('jxgbox7', {axis:true,keepaspectratio:true}); board.create('circle', [ [2, 1.5], 2]);

## "mouseup" now replaced by "up"

The `mouseup`

event should be replaced by the generic `up`

event, since IE 11 sends pointerup instead of mouseup. (IE as usual messing with everyone's head.)

The point A on this board randomly changes position each time you release the mouse.

var board = JXG.JSXGraph.initBoard('jxgbox8'); var p = board.create('point', [-2, 3]); board.on('up', function () { xRand = -5+10*Math.random(); yRand = -5+10*Math.random(); p.setPosition(JXG.COORDS_BY_USER, [xRand,yRand]); });

## Change color of infobox

The infobox appears when you mouseover a point, and it gives the *x-* and *y-*coordinates of the point.

Here, the point P's infobox is red, while Q's infobox is the default black.

var board = JXG.JSXGraph.initBoard('jxgbox9'); var p = board.create('point', [1,1],{name:'P'}); p.setAttribute({scaleSymbol: 'ft'}); var q = board.create('point', [-2,-1],{name:'Q'}); p.on('over', function () { board.infobox.setProperty( {strokeColor: 'red'} ); }); q.on('over', function () { board.infobox.setProperty( {strokeColor: 'black'} ); });

## Rotate Text

Board dimensions need to be square - otherwise text is scaled to board scale...!!!

I found this feature was quite limited and gave up on it. I opted to use CSS transforms instead for the Biorhythm Graphs page.

JXG.Options.text.display = 'internal'; var board = JXG.JSXGraph.initBoard('jxgbox10', {axis:true}); txt = board.create('text',[-2,-1, 'Hello World']); // Rotate text around the lower left corner (-2,-1) by 90 degrees. var tRot = board.create('transform', [Math.PI/2, -2,-1], {type:'rotate'}); tRot.bindTo(txt); board.update();

## Drag axis for scaling (2) - better!

This is an attempt to replicate GeoGebra's axis scaling, where you can drag the axes to scale them.

It seems this is not possible to replicate in JSXGraph (yet), but this shows one possible way to do it.

## Use slider for axis scaling

This shows one way to change *x*- and *y*-axis scaling using sliders.

The sliders sit on their own boards, separate from the main board, and are connected via `boardX.addChild(board)`

## Removing highlights and selection of board elements

It often happens when dragging objects on the board that axis labels and text annoyingly gets highlighted.

Stop selection of text and other board elements when dragging objects with the following in the CSS (apply it to the board):

-webkit-touch-callout:none; -webkit-user-select:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none;

To prevent the cursor changing to "select" type (i.e. indicating text), use in the CSS:

cursor:default

The copyright notice and Navigation are removed with:

showCopyright:false, showNavigation:false

## Zoom and Pan

From this Stackoverflow response dated 30 Apr 2014.

"The zoom property is not of type boolean."

You can zoom in or out of the graph while holding down the <Shift> key and moving the mouse wheel, if the following is set as a property of the board.

grid:true, zoom: { factorX: 1.25, factorY: 1.25, wheel: true, needshift: true, eps: 0.1 }

By default, you can **pan** left, right or up, down while holding down the <Shift> key and dragging the graph.

## Log-log and semi-log axes

This was a bit tricky since it fell over when the version changed. It appears to be working now.

var x, ticksX, ticksY, p, f1, f2, f3, xAxis, yAxis, pre, post; var board = JXG.JSXGraph.initBoard('jxgbox15',{axis:false}); xAxis = board.create('line', [[0, 0], [1, 0]]); yAxis = board.create('line', [[-4, 0], [-4, 1]]); ticksX = board.create('ticks', [xAxis, 1], { drawLabels: true, drawZero: true, generateLabelText: function (tick, zero) { return (Math.pow(10, Math.round(tick.usrCoords[1] - zero.usrCoords[1]))).toString(); } }); ticksY = board.create('ticks', [yAxis, 1], { drawLabels: true, // Show the tick marker at zero (or, in this case: 1) drawZero: true, generateLabelText: function (tick, zero) { return (Math.pow(10, Math.round(tick.usrCoords[2] - zero.usrCoords[2]))).toString(); } }); p = board.create('point', [3, 3]); // overwrite the contents of the default infobox. board.highlightInfobox = function (x, y, el) { board.infobox.setText('(' + JXG.trunc(Math.pow(10, x), 4) + ', ' + JXG.trunc(Math.pow(10, y), 4) + ')'); }; pre = function (x) { return Math.pow(10, x); }; post = function (x) { return Math.log(x) / Math.LN10; }; f1 = function (x) { return x*x;}; f2 = function (x) { return 1 + Math.exp(x);}; board.create('plot', [function (x) { return post(f1(pre(x))); }], { name: 'f1', withLabel: true }); board.create('plot', [function (x) { return post(f2(pre(x))); }], { name: 'f2', withLabel: true, strokeColor: 'red' });