# JSXGraph: interactive javascript graphs

By Murray Bourne, 26 May 2010

I've been investigating JSXGraph over the last few weeks and I'm quite impressed.

JSXGraph is a javascript-based grapher from the mathematics people at the University of Bayreuth in Germany.

• It works in all major browsers and is cross-platform.
• It even works on Apple's iPod touch, iPhone and iPad, since it is not Flash- or java applet-based.
• No upload of any files - all the programming is done within the <script> tags on the page.
• Once the user has downloaded the actual JSXGraph script to their browser (76.2 kB on a gzipped server), the file sizes are very small (this page is only about 12 kB).
• Easy to implement with only 3 text-based elements: (a) A call to the JSXGraph javascript file (jsxgraphcore.js); (b) An empty "div" tag to hold the graph; and (c) The javascript that describes your graph
• Much smaller than java applets and much less clunky
• No need for a plugin of any sort - just javascript which is enabled by default on virtually all browsers
• There are many demo examples on which you can base new projects
• Compared to graphs with SVG, there are less compatability issues
• If I need to change anything, it's just a change to the code. This is much easier compared to development in Flash, where I would need to open the third party application (Flash), make the change, create the SWF file, then upload the SWF file to the server
• It works in a WordPress blog, as you can see below. There's a JSXGraph WordPress plugin under development.

• You really need to have a good understanding of javascript to get anything worthwhile out of JSXGraph (you can view the page source for this page to see how it is done). So it's not really a "plug and play" application (there are no WYSIWYG interfaces or wizards), so it's not really that friendly if you want newbie students to develop new applications using it. [Update: This is my attempt to provide a user-friendly grapher: Plot graphs using JSXGraph]
• The documentation is still rather sparse (since it is quite a new development). So there's quite a bit of "guess and check" involved.

JSXGraph doesn't behave all that well in Internet Explorer. But this is not JSXGraph's fault - it's just one of IE's many irritations. It still works, but (for example) IE does not display the grid scale (numbers on the axes) in the examples on this page. But at least it works.

This wiki contains lots of examples: Showcases

## Examples using JSXGraph

The following examples are my recent efforts. Most are based on existing examples in the JSXGraph site.

## Investigate Slope and y-intercept of a Straight Line

With this one you can drag either point A or point B, and you can see the resulting linear equation in the form y = mx + b. You could use this to investigate what the equation of a straight line is when you have:

• A horizontal line (What is m? What is b?)
• A vertical line (What is m? What is b?)
• A line through the origin (What is m? What is b?)

var b = board = JXG.JSXGraph.initBoard("jxgbox3", {showCopyright:false,boundingbox:[-5,5,5,-5], axis:true});
p1 = b.createElement('point',[0,1],{fillColor:'#ff00ff'});
p2 = b.createElement('point',[3,-1],{fillColor:'#ff00ff'});
line = b.createElement('line',[p1,p2]);

el2 = b.create('text',[-3,3.8,
function(x){
return "y = " +Math.round(10*((p2.Y()-p1.Y())/(p2.X()-p1.X())))/10+" x + " +
Math.round(10*(p1.Y()-p1.X()*(p2.Y()-p1.Y())/(p2.X()-p1.X())))/10
}
]
);



At the bottom right of each screen is a facility to zoom in (the "+" sign) and pan left right and up-down. Try it!

## Ellipse

With this one you can drag point D around the ellipse. In this case the equation of the ellipse is: $\frac{x^2}{64}+\frac{y^2}{25}=1$.

Points A and B are each at a focus of the ellipse (these points are fixed).

You could use this one to investigate the property that Length AD + Length BD is constant for a particular ellipse.

[In this example, AD + BD = 16. It jumps to 15.9 occasionally because of rounding.]


var brd = board = JXG.JSXGraph.initBoard("jxgbox6", {showCopyright:false,boundingbox:[-10,10,10,-10], axis:true});
var qr = [];
qr[5] = brd.create('point', [-Math.sqrt(39),0], {fixed:true,style:3,strokeColor:'blue',fillColor:'blue'});
qr[6] = brd.create('point', [Math.sqrt(39)+0.1,0], {fixed:true,style:3,strokeColor:'blue',fillColor:'blue'});
qr[7] = brd.create('point', [0,5], {style:3,strokeColor:'blue',fillColor:'blue',visible:false});
var ell = brd.create('ellipse',[qr[5],qr[6],qr[7]]);
g = brd.create('glider', [3,2.7,ell], {style:5,fillColor:'#ff00ff'});
var li1 = brd.createElement('segment',[qr[5],g],
{strokeWidth:2, strokeColor:'#dddddd'});
var lim = brd.createElement('segment',[qr[6],g],
{strokeWidth:2, strokeColor:'#dddddd'});
el2 = brd.create('text',[-6,8,
function(x){

BDdeltXsq = (g.X()-qr[6].X())*(g.X()-qr[6].X());
BDdeltYsq = (g.Y()-qr[6].Y())*(g.Y()-qr[6].Y());
BD = Math.floor(10*Math.sqrt(BDdeltXsq+BDdeltYsq))/10;
}
],{fontSize:14+'px'}
);



## Random Balls

You can even do animations with JSXGraph. Here are moving random balls. This uses javascript's "setInterval" time function.

You can't actually do anything in this one - just allow yourself to get hypnotized!


var brd = JXG.JSXGraph.initBoard("jxgbox5", {showCopyright:false,boundingbox:[-0.2,1.2,1.2,-0.5], axis:false});
p = [];
len = 25;
for (i=0;i<len;i++) {
strokey = '#'+Math.floor(Math.random()*16777215).toString(16);
if(strokey.length ==6) {strokey = strokey+'f';}
if(strokey.length ==5) {strokey = strokey+'ff';}
filly = '#'+Math.floor(Math.random()*16777215).toString(16);
if(filly.length ==6) {filly = filly+'f';}
if(filly.length ==5) {filly = filly+'ff';}
p[i] = brd.createElement('point',[Math.random(),Math.random()],
{face:'o', size:10, strokeColor:strokey, fillColor:filly, fillOpacity:0.4, strokeOpacity:0.4, withLabel:false});
}
setInterval(function(){
var i, j;
for (i=0;i<p.length;i++) {
p[i].moveTo([Math.random(),Math.random()],1000);
}
i = 0;

},2000);



## Pentagon

Drag point A to change the size and position of the pentagon.


var berd = JXG.JSXGraph.initBoard("jxgbox4", {showCopyright:false,boundingbox:[-10,10,10,-10], axis:true,keepaspectratio:true});
var pa1 = berd.createElement('point',[0,0], {name:'O',style:3,strokeColor:'blue',fillColor:'blue'});
pa1.setProperty({fixed:true});
var pa2 = berd.createElement('point',[2,4], {name:'A',style:6,strokeColor:'#ff00ff',fillColor:'#ff00ff'});
var pa3 = berd.createElement('point',[-2,-3], {name:'B',style:3,strokeColor:'blue',fillColor:'blue'});
var pa4 = berd.createElement('point',[1,-1], {name:'C',style:3,strokeColor:'blue',fillColor:'blue'});

var pa5 = berd.createElement('point',[-3,1], {name:'D',style:3,strokeColor:'blue',fillColor:'blue'});

var poly = berd.createElement('regularpolygon',[pa1,pa2,pa3,pa4,pa5]);



## Investigate Sine Curve - Amplitude and phase shift

Move the magenta dot up and down or left and right to investigate the amplitude and phase shift of a sine curve.

The equation of the curve appears in the form y = a sin (bx + c)


var bored = JXG.JSXGraph.initBoard("jxgbox2", {showCopyright:false,boundingbox:[-10,10,10,-10], axis:true,keepaspectratio:true});

pp = bored.createElement('point',[0,1],{style:6,name:'A',fillColor:'#ff00ff'});
bored.createElement('functiongraph', [function(x){return pp.Y()*Math.sin(x-pp.X());}]);

el1 = bored.create('text',[1,3.2,"Drag the dot, left-right, up-down"]);
el2 = bored.create('text',[-7,7,

function(x){
if(pp.X()<0) {
return "y = " +(pp.Y()).toFixed(2)+" sin (x + " + Math.abs((pp.X()).toFixed(2)) +")";
} else {
return "y = " +(pp.Y()).toFixed(2)+" sin (x - " + (pp.X()).toFixed(2) +")";
}
}
],{fontSize:14+'px'}
);



## Graphs using polar coordinates

This one lets you change the angle for a function of the form r = f(θ), where we are using polar coordinates.

Drag the blue dot left and right (slowly) along the slider to change the angle and to see the resulting length r.

The magenta curve starts when θ = 0.


var board = JXG.JSXGraph.initBoard("jxgbox1", {showCopyright:false,boundingbox:[-5.5,6.5,5.5,-3], axis:true,keepaspectratio:true});
q = board.createElement('slider', [[-2.5,5.9],[2.5,5.9],[-Math.PI,2,4*Math.PI]],
{strokeColor:'blue',fillColor:'blue',style:6, name:'&theta;'});
// out of sight
c = board.createElement('slider', [[0,-10],[3,-10],[-4*Math.PI,0,0]], {style:6, name:'c',visibility:false});

//inst = board.create('text',[-4.7,3.9,"Drag the dot left or right"],{fontSize:16,face:'Arial'});
c1 = board.create('circle',[[0,0],1],{strokeColor:'#bfbfbf', strokeWidth:1});
c2 = board.create('circle',[[0,0],2],{strokeColor:'#bfbfbf', strokeWidth:1});
c3 = board.create('circle',[[0,0],3],{strokeColor:'#bfbfbf', strokeWidth:1});
c4 = board.create('circle',[[0,0],4],{strokeColor:'#bfbfbf', strokeWidth:1});
c4 = board.create('circle',[[0,0],5],{strokeColor:'#bfbfbf', strokeWidth:1});

line0 = board.create('segment',[[-5,0],[5,0]],{strokeColor:'#bfbfbf', strokeWidth:1});
line1 = board.create('segment',[[0,-5],[0,5]],{strokeColor:'#bfbfbf', strokeWidth:1});
line2 = board.create('segment',[
[-5*Math.cos(Math.PI/6),-5*Math.sin(Math.PI/6)],
[5*Math.cos(Math.PI/6),5*Math.sin(Math.PI/6)]],
{strokeColor:'#bfbfbf', strokeWidth:1});
line3 = board.create('segment',[
[-5*Math.cos(Math.PI/3),-5*Math.sin(Math.PI/3)],
[5*Math.cos(Math.PI/3),5*Math.sin(Math.PI/3)]],
{strokeColor:'#bfbfbf', strokeWidth:1});
line4 = board.create('segment',[
[-5*Math.cos(-Math.PI/6),-5*Math.sin(-Math.PI/6)],
[5*Math.cos(-Math.PI/6),5*Math.sin(-Math.PI/6)]],
{strokeColor:'#bfbfbf', strokeWidth:1});
line5 = board.create('segment',[
[-5*Math.cos(-Math.PI/3),-5*Math.sin(-Math.PI/3)],
[5*Math.cos(-Math.PI/3),5*Math.sin(-Math.PI/3)]],
{strokeColor:'#bfbfbf', strokeWidth:1});

t0 = board.create('text',[5.1,0,"0"],{fontSize:14+'px'});
t0a = board.create('text',[-5.3,0.1,"&pi;"],{fontSize:14+'px'});

xoffset = -1.6;
var i;
for(i=-1;i<5;i++)
{
if(i==-1){
board.create('text',[xoffset+i,5.5,"&minus;&pi;"],{fontSize:14+'px'});
}else if(i==0){
board.create('text',[xoffset+i,5.5,"0"],{fontSize:14+'px'});
}else if(i==1){
board.create('text',[xoffset+i,5.5,"&pi;"],{fontSize:14+'px'});
}else{
board.create('text',[xoffset+i,5.5,i+"&pi;"],{fontSize:14+'px'});
}
}
myFunc = board.create('text',[1.8,5,"Function: r = 2 + 3 sin &theta;"],{fontSize:14+'px'} );
function plot(){
function r(t) {return 2+3*Math.sin(t); }
graph = board.createElement('curve', [
r, [0,0],
function() {return c.Value();},
function() {return q.Value();}
],
{curveType:'polar',strokeColor:'#ff00ff', strokeWidth:1}
);

function p(t){return (2+3*Math.sin(q.Value()))*Math.cos(q.Value()) };
function s(t){return (2+3*Math.sin(q.Value()))*Math.sin(q.Value()) };
function m(t) {return "r = "+Math.round(100*(Math.sqrt(p(t)*p(t) + s(t)*s(t))))/100  };
graph2 = board.create('segment',  [[0,0],[p,s]],
{strokeColor:'black', strokeWidth:1}
);
function p1(t){return p(t)+0.2};
function s1(t){return s(t)+0.2};
text1 = board.create('text',[p1,s1,m],{fontSize:12+'px'});
board.update();
};
plot();
copy = board.create('text',[-5.2,-5,"Copyright &copy; www.intmath.com"],{fontSize:12+'px'} );



You can see more examples of polar coordinate graphs using JSXGraph (in the answers) on this page: Curves in Polar Coordinates

Also see Radians - an Introduction for a lesson which includes a JSXGraph interactive.

## Conclusion

JSXGraph is a useful addition for those of us who want to create interactive math graphs. It is cross-browser and cross-platform, easy to implement, but takes some javascript knowledge to develop new graphs.

### 11 Comments on “JSXGraph: interactive javascript graphs”

1. vonjd says:

BTW: The creator of this nifty piece is the university of Bayreuth in Germany (Bayreuth is also well known for its annual Wagner Festival, where you have to wait years to get tickets.)

2. Murray says:

Thanks, Vonjd. In my enthusiasm to publish, I forgot to add that detail.

I have amended the post.

3. More Press « Random Walks says:

[...] reading through the carnival, I was especially interested in (as a math teacher), JSXGraph, an interactive graphing application that you can easily embed in webpages using javascript. [...]

4. posoft says:

Hello,
I would like to know that is this scrip support to opera or mozilla firefox.
Thanks

5. Murray says:

Hi posoft. Yes, JSXGraph is cross-browser and cross-platform. That's one of its main advantages.

6. Thomas Somah says:

I used to have problems with radians and degrees until I went through your radians article today. The explanations are fantastic.

Please keep up the good work.

God bless
Thomas

7. Murray says:

Hi Thomas. Glad you found the article useful!

8. anwar says:

mathematics become easier and understandable when demonstrated through audio vidio aids in a mathematics lab

Very Good work, will help my children visualize what is going on in Calculus.

10. john says:

Hi all,
This javascript graphing display sounds interesting, so I have a question:
Context: server side database passing SQL/Access data to a dynamic web page (ie: created on the fly). I want to take this interactive further.

a) I see one can easily manipulate simple graphics by the user but can I pass user manipulated data back to server in a stream for recalculation on the server side, if necessary? AJAX, etc. stream data.

I presume one can build 2nd, 3rd order derivative graphical displays - what limitations are introduced or does this interactive build on javascript?

11. Murray says:

@John: You should be able to do Ajax calls from JSXGraph.

Also, it is possible to do higher order graphs. See here for an example.

### Comment Preview

HTML: You can use simple tags like <b>, <a href="...">, etc.

To enter math, you can can either:

1. Use simple calculator-like input in the following format (surround your math in backticks, or qq on tablet or phone):
a^2 = sqrt(b^2 + c^2)
(See more on ASCIIMath syntax); or
2. Use simple LaTeX in the following format. Surround your math with $$ and $$.
$$\int g dx = \sqrt{\frac{a}{b}}$$
(This is standard simple LaTeX.)

NOTE: You can't mix both types of math entry in your comment.