How to Create a Javascript Program
The browser on your desktop is a computing engine with a well-designed user interface. Behind the interactive environment, it can read local HTML files and execute programs written in javascript. This page is a step-by-step guide to working in that enviroment, with examples and links to get you started with using it as a research tool.
The prescription here will take you step by step to the creation and use of Javascript for data visualization with a Python foundation. A good book to follow up with is
Data Visualization with Python and JavaScript
published by O'Reilly and written by Kyran Dale. In the preface, he writes
"Python's simplicity and power was a breath of fresh air ... Python was the perfect glue, playing nicely with C++ libraries ... and doing, with consummate ease, all the stuff that is such a pain in low-level languages. ... I started to write all my graphical user interfaces (GUIs) and visualizations in Python. "
He notes that javascript and web browsers are "the perfect universal distribution system for the software I'd so lovingly crafted." He adds that javascript and HTML5 is faster than Python, and that visualizations in Python
"are now possible on your local web browser, and the payoff is that, with very little effort, they can be made accessible to every desktop, laptop, smartphone, and tablet in the world."
Begin with Python
In order to get started you will need a local web server. Since most likely you will not have one running that is easily accessible, a simple solution is to use python to provide one for you. Python has a built-in module that will run a server and that can be started with one line of python code.
First, identify the directory or folder on your computer under which all of the javascript you want to access is stored. Then, at the top level of that directory, run this program
python -m CGIHTTPServer 8000 1>/dev/null 2>/dev/null &
By using port 8000 the server is distinct from the one on port 80 used for web applications. The site would appear by putting
http://localhost:8000
in a Google Chrome or Mozilla Firefox browser window running on the same user account on the same machine. Note the redirects for stdio and stderr to /dev/null keeps output from appearing in the console. The server may be killed by identifying its process ID in Linux with the command
ps -e | grep python
followed by
kill -s 9 pid
where "pid" is the ID number found in the first line. Alternatively, if it is the only python process running you may kill it with
killall python
Any file in the directory tree below the starting directory is now accessible in the browser, and html files will be parsed to run the included javascript. If here is a cgi-bin directory at the top level, the server will see it and use it. One use of this low level server is to create a virtual instrument that is accessible from the web, but not exposed to it directly. A remote web server on the same network that can access port 8000 on the instrument machine can run code and get response from the instrument by calling cgi-bin operations.
For programmers, however, this utility allows development and debugging of web software without the need for a large server.
Add a Directory for a Program
Put each program (think webpage) into its own directory under this top level directory. That way, when you open the browser to localhost:8000 you will see list of directories each containing a separate application. Click on one of those and your application, or its files, will open.
Under that program directory create at a minimum two other subdirectories:
js will contain the javascript code css will contain styling code if you want to implement it
Your javascript programs will have the extension ".js" and should be located in the js subdirectory. This structure is optional, but keeping to the pattern will make writing and rewriting programs easier later.
The browser will automatically see a file "index.html" in a directory if that file exists. For development it is best not to use "index.html" as the base file for your application, but instead to use another descriptive name such as "calculator.html" or "orbits.html". Later, if you want it to open without the extra click you can rename it, or in Linux and other Unix-like operating systems create a soft link that points to it with the command line
ln -s calculator.html index.html
The browser will see the index soft link and then open the file it points to. By not having "index.html" in your program directory you will be able to browse other files there, try variants on your program, or inspect code in the browser.
Select a Browser
There are two browsers that are recommended for this type of development, and the choice at least at this beginning stage is a matter of style and convenience. The user interface to development help is different, and actually the "engine" they run is also different. As the web develops, the programmers who create and maintain browsers also change what they can do, and sometimes what they allow the browsers to do. There are two recommend choices, which run different engines.
Google Chrome currently with 62% of desktop use, it is full-featured with significant memory usage and CPU requirements.
Mozilla Firefox currently with 15% of desktop use it was widely more popular before the rise of Chrome. Firefox is the least restrictive and most open of the two. Its requirements for memory and CPU are lower than Chrome. Firefox perhaps should be the development platform choice unless you need the Google features.
Both have developer consoles. These are windows on the engine, revealing what happens as code executes, and containing messages you may request by embedding commands within javascript.
In Google Chrome, click the three dots at the upper right of the browser window, select "More tools" and "Developer tools". By default it will open to the Console on the right side of the browser.
In Firefox click the three bars at the upper right, then the "Developer" icon, and "Web console". It will open at the bottom of the browser.
HTML
For the simplest of pages, create a file and give it an extension ".html" on Linux or Mac, or perhaps "htm" in Windows. This is the code the browser will execute first. If you name it "index.html" when the browser is pointed to the directory containing the it will open it automatically. For development, this is not desirable behavior because you will also want to open other files in the browser to inspect them, or to run alternative versions in the same directory tree. Therefore, refrain from using "index.html", and try instead some other descriptive name. In this example we will call it "orbits.html".
The simplest html could look like this
<!DOCTYPE html> <html lang="en">
<head> <title>Run a Javascript Example</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum- scale=1.0"> <meta name="description" content="Javascript Example"> <script src="js/example.js"></script> </head> <body>
<!- Comments in HTML are between these markup commands. ->
A description or instructions could go here.
</body> </html>
I have used indenting to distinguish sections. That's not required. HTLM skips extra spaces and line feeds. That is why, if you use a program to create website content, the result may be unreadable in an editor. At this stage, write the HTML in a text editor and use clear spacing and indentation so you can read it and understand what you have written months later.
The elements shown here include most of those that are needed for bare-bones web content. However, for anything more you will need styling files, called "css" files, and javascript code that is executed when the browser needs it. The code can be in a separate file, and those should be kept in a "js" directory for organization. Some of them will be libraries you will use, others could be your own code. Optionally you may include javscript code in-line in the HTML by using a <script> ... </script> markup.
We will use an orbit simulator as a demonstration. You can find the complete code here. It begins this way
<!doctype html> <html lang="en"> <html> <head> <title>Explore Solar System Orbits in 3D</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <meta name="description" content="Properties of a Vector Viewed in Three.js"> <script src= "./js/vector3D.js"></script> <script src= "./js/forces3D.js"></script> <script src= "./js/phys.js"></script> <script src= "./js/astro.js"></script> <script src= "./js/three.min.js"></script> <script src= "./js/OrbitControls.js"></script> <script src= "./js/dat.gui.min.js"></script> <link rel="stylesheet" href="css/dat.css"> <link rel="stylesheet" href="css/main.css"> </head>
All of the javascript files are in the local "js" directory. The "./js" means take the js in the current working directory. All of them provide libraries for the code to follow. Javascript reads files sequentially. The ones which follow depend on what comes ahead.
Also in this example we have the style files in the css directory. These instruct the browser in the appearance of the page, and in the case of dat.gui.min.js and its dat.css, provide a nice user interface. One feature of javascript is that the code can be compressed to remove white space. It is unreadable, but it shortens the length of the file. Often libraries are provided in both full-form and minimized form. Here three.min.js provides 3D libraries in a packed file. The full libary is described here
After this block which initiates the browser the <body> has the actual instructions.
<body>
<script src= "./js/explore_orbits.js"></script>
</body> </html>
This part of it executes the javascript code "explore_orbits.js" which is in the "js" directory. That's where the work is done.
Following that, other code fills in the page, provides the help pages, and completes the html. We will not show all of it here, but you can view it in the orbits.html example. It would have other
sections. The css files connect the content with the styling for each one.
Writing Javascript
Typical javascript from the past would be used to perform tricks for the website, provide interactivity, do some simple calculations. Where the browser has power over working with pure Python on the desktop is in visualization. That is why we picked this particular example. It offers an interactive user interface with 3D navigation, simulation of a 3D scene, and a physics simulation of the orbit. The code we use has been adapted from work by Dev Ramtal you will find on Github
along with many other interesting applications.
The best way to understand the code is to look at in total but we can highlight a few parts of it. It begins this way
// Rendering var width = window.innerWidth, height = window.innerHeight; var scene, camera, renderer;
// Rime-keeping variables var dt1 = 1/24; // simulation time unit is 1 day; time-step is 1 hr var dt6 = 1/4; // time step is 6 hr var dt = dt1; ; var numSteps = 4*8760; // 1 year; 365*24 var animFreq = numSteps; // once per week; 24*7 var t = 0; var nSteps = 0;
// Gravitational constant var G;
// sun variables var center; var massSun; var radiusSun = 30;
The full description of the language and its features is available on line.
This is clear without much explanation. The "var" declares variables that are used subsequently. A variable defined outside of a function, at the top of the file, is known to all the other components in the file. Variables can be initialized in the declaration, or assigned and changed later. Javascript data types are dynamic and can be changed later; it has only one type of number. Unlike Python, where writing "r = 30" would make "r" an integer, and "r = 30. " would make it a floating point number, in javascript it's all the same.
Next comes code that actually runs the javascript program when the browser opens the window:
window.onload = init;
function init(){
setupScaling(); setupPlanetData(); setInitialConditions(); setupObjects();
initializeListeners();
animFrame(); //simulate(); //renderer.render(scene, camera);
}
Of note here is the function defined by identifying it by name, and then within {...} including the commands that are to be executed. Here, init() calls other functions. It could as well define and excute specific code. An example, well down in the code, is the part using the Threejs library to create spheres. It looks like this
var sphereGeometry = new THREE.SphereGeometry(radiusSun,20,20);
var sphereMaterial = new THREE.MeshLambertMaterial({color: 0xffff00}); sun = new THREE.Mesh(sphereGeometry,sphereMaterial); scene.add(sun);
These lines create a sphere in the 3D space simulated by the browser. The browser engine used the graphics processor of your computer (the GPU) to show it effectively as you interact with the display. Some other parts of the code turn on interrupts that change the point of view as you click or move the mouse.
While this is going on, some other code is running as well.
function animFrame(){
animId = requestAnimationFrame(animFrame); onTimer();
} function onTimer(){ if ( userControls.runsim ) {
if (nSteps < numSteps){ simulate();
updateDisplay(gui);
renderer.render(scene, camera); }else{ stop(); } nSteps++;
} else { renderer.render(scene, camera); } }
The first function "animFrame()" runs the changing view on the screen. The imbedded "onTimer()" function steps the scene frame by frame. At each step, a simulation is run and then the results are displayed. Another scene is created and displayed in the next cycle. It was called by init(), when the screen opened. The function requestAnimationFrame() is part of the Threejs library. It does the animation in a cross-platform, browser-independent way.
The simulation that runs each cycle steps the physical time (that is "dt" here). At each time it runs a Runge-Kutte integration using physics, then moves the planets one by one.
function simulate(){
if ( userControls.runfast )
{ dt = dt6; t += dt; } else { dt = dt1; t += dt;
}
for (var n=0; n<numPlanets; n++){
RK4(n); movePlanet(n); }
}
The routine RK4() is where the physics is controlled. Within it there is a call to getAcc() which accelerates the planets based on gravitational interaction:
function getAcc(ppos,pvel,pn){
var massPlanet = planets[pn].mass; var r = ppos.subtract(center); // force exerted by sun var force = Forces3D.gravity(G,massSun,massPlanet,r); // forces exerted by other planets for (var n=0; n<numPlanets; n++){ if (n!=pn){ // exclude the current planet itself! r = ppos.subtract(s[n]); var gravity = Forces3D.gravity(G,masses[n],massPlanet,r);; force = Forces3D.add([force, gravity]); } } // acceleration return force.multiply(1/massPlanet);
}
Lastly, within this you see a call to Forces3D. gravity() that is in a file loaded at the beginning. Here is an example of how to call up a function from a js file loaded by the <script> tag. "Forces3D" is the file name, and "gravity" is the function within it. A look at that file shows how it is built.
function Forces3D(){ }
Forces3D.gravityModified = function(G,m1,m2,r,eps){ return r.multiply(-G*m1*m2/((r.lengthSquared()+eps*eps)*r.length())); }
It shows obviously that Newtonian gravitation is the foundation of the entire code.
Executing Javascript and HTML
You can run this code in your Python web server browsing to localhost:8000 and picking out orbits.html. You will also find a version of it on our server live here:
Inner planets orbit simulation