Web-Based Visualization
Web Technologies Suitable for (Interactive) Visualization and Related Opportunities
-- Ove Daae Lampe
Web Technologies Suitable for (Interactive) Visualization and Related Opportunities
-- Ove Daae Lampe
Ove Daae Lampe
+Ove Lampe | ii.uib.no/vis | cmr.no/cmr_computing
Researcher at CMR Computing and PhD Student at UiB

Slides are available here: http://folk.uib.no/ola062/test_talk
HTML5 ≈ HTML + Javascript + | Java | 12,000,000 | ![]() |
| Flash | 10,900,000 | |
| Javascript | 8,320,000 | |
Results after a google search for Visualization +Java|Flash|Javascript (24.10.2011)
Adobe Flash (formerly Macromedia Flash) is a multimedia platform used to add animation and interactivity to web pages.
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995. Java can be utilized online on webpages through applets.
HTML 5 is the fifth revision of the HTML standard created in 1990. Its core aims has been to improve the language with support for the lates multimedia.
Several new features increases the semantic value of documents: <section> , <article> and <header>.
The following added features adds possibilities in terms of multimedia, and visualization.
HTML5 has defined extended APIs such as:
W3.org defines it's new features as following:
Semantics: Give a meaning to structure using RDFa, microdata and microformats.
Offline and Storage: Web Apps can start faster and work with no internet connection.
Device Access: The Geolocation API, touch, and even tilt orientation.
Connectivity: Web Sockets and server-sent events means faster and more efficient communications.
Multimedia: Audio and video are first class citizens of the HTML 5 web.
3D, Graphics & Effects: SVG, Canvas, WebGL and CSS3 3D features.
Performance and Integration: Web workers and XMLHttpRequest 2
CSS3: New stylization and effects, enhancing the web without sacrificing your semantic structure.The <canvas> is created using:
<canvas id="tutorial" width="150" height="150"
style="border:solid black 1px;"></canvas>
which creates the following:
Canvas exist in a 2D and in a 3D mode. We access the 2D context using:
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
}
This context, ctx, can be utilized for immediate mode 2D rendering, e.g.,:
ctx.beginPath(); ctx.moveTo(30, 30); ctx.lineTo(150, 150); ctx.bezierCurveTo(60, 70, 60, 70, 70, 150); ctx.lineTo(30, 30);
<html>
<head>
<script type="application/javascript">
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect (10, 10, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (30, 30, 55, 50);
}}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="150" height="150"></canvas>
</body>
</html>
Html code using the Canvas tag:
<body onload="webGLStart();">
<canvas id="mycanvas" width="500" height="500"></canvas>
</body>
And the webGLStart method:
function webGLStart() {
var canvas = document.getElementById("mycanvas");
initGL(canvas);
initShaders();
initBuffers();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST);
drawScene();
}
var gl; // Define a 'global' GL-context variable
function initGL(canvas) {
try {
gl = canvas.getContext("webgl");
} catch (e){
try {gl = canvas.getContext("experimental-webgl");}catch (e){}
}
if (gl){
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} else {
alert("Could not initialise WebGL, sorry :-(");
}
}
Define a fragment shader:
<script id="shader-fs" type="x-shader/x-fragment">
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
</script>
And a vertex shader:
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 vertex;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(vertex, 1.0);
}
</script>
Create our vertex buffer (no immediate mode!)
var pos_buf;
function initBuffers() {
pos_buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pos_buf);
var vertices = [
0.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array(vertices),
gl.STATIC_DRAW);
pos_buf.itemSize = 3;
pos_buf.numItems = 3;
}
Render the scene
function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Create the perspective matrix pMatrix
mat4.perspective(45, gl.viewportWidth / gl.viewportHeight,
0.1, 100.0, pMatrix);
mat4.identity(mvMatrix); // Reset our modelview matrix
// Bind our vertex array (attrib array)
gl.bindBuffer(gl.ARRAY_BUFFER, pos_buf);
// Bind the vertex array to the shader attrib
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
pos_buf.itemSize, gl.FLOAT, false, 0, 0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLES, 0, pos_buf.numItems);
}
Create a WebGLRenderer
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(document.body.clientWidth,
document.body.clientHeight);
document.body.appendChild(renderer.domElement);
And change its background color
renderer.setClearColorHex(0xEEEEEE, 1.0);
renderer.clear();
Create a Camera
// new THREE.Camera( FOV, viewAspectRatio, zNear, zFar );
var camera = new THREE.Camera( 45, width/height, 1, 10000 );
camera.position.z = 300;
Make a Scene with a Cube
var scene = new THREE.Scene();
var cube = new THREE.Mesh(new THREE.CubeGeometry(50,50,50),
new THREE.MeshBasicMaterial({color: 0x000000}));
scene.addChild(cube);
And render the Scene as seen by the Camera
renderer.render(scene, camera);
Adding light, shadows, and animation
// enable shadows on the renderer renderer.shadowMapEnabled = true; // enable shadows for a light light.castShadow = true; // enable shadows for an object litCube.castShadow = true; litCube.receiveShadow = true; // Adding the animation litCube.position.x = Math.cos(t/600)*85; litCube.position.y = 60-Math.sin(t/900)*25; litCube.position.z = Math.sin(t/600)*85; litCube.rotation.x = t/500; litCube.rotation.y = t/800;
var grid = /* 2D Array */
var barGraph = new THREE.Object3D();
scene.addChild(barGraph);
var max = /* Grid max value */
var mat = new THREE.MeshLambertMaterial({color: 0xFFAA55});
for (var j=0; j<grid.length; j++) {
for (var i=0; i<grid[j].length; i++) {
var barHeight = grid[j][i]/max * 80;
var geo = new THREE.CubeGeometry(8, barHeight, 8);
var mesh = new THREE.Mesh(geo, mat);
mesh.position.x = (i-grid[j].length/2) * 16;
mesh.position.y = barHeight/2;
mesh.position.z = -(j-grid.length/2) * 16;
mesh.castShadow = mesh.receiveShadow = true;
barGraph.addChild(mesh);
}
}
var scatterPlot = new THREE.Object3D();
var mat = new THREE.ParticleBasicMaterial(
{vertexColors: true, size: 1.5});
var pointCount = 10000;
var pointGeo = new THREE.Geometry();
for (var i=0; i<pointCount; i++) {
var x = Math.random() * 100 - 50;
var y = x*0.8+Math.random() * 20 - 10;
var z = x*0.7+Math.random() * 30 - 15;
pointGeo.vertices.push(new THREE.Vertex(new THREE.Vector3(x,y,z)));
pointGeo.colors.push(new THREE.Color().setHSV(
(x+50)/100, (z+50)/100, (y+50)/100));
}
var points = new THREE.ParticleSystem(pointGeo, mat);
scatterPlot.addChild(points);
scene.fog = new THREE.FogExp2(0xFFFFFF, 0.0035);
Using DAT.GUI:
var gui = new DAT.GUI();
gui.add(cube.scale, 'x').min(0.1).max(10).step(0.1);
gui.add(cube.scale, 'y', 0.1, 10, 0.1);
gui.add(cube.scale, 'z', 0.1, 10, 0.1);
Done!
The ChemDoodle components greatly simplifies visualizing protein, and other molecular structures.
<script>
// setup component
var cdcanvas = new ChemDoodle.TransformCanvas3D(
'cnv_name', 400, 400);
// set the representation to 'Ball and Stick'
cdcanvas.specs.set3DRepresentation('Ball and Stick');
// set the background color to black
cdcanvas.specs.backgroundColor = 'white';
// load data
var molFile = '3036\n CHEMDO83D\n\n 28 29 0 .... END\n';
// set the coordinate multiplier to 1 to stay in Angstroms
var molecule = ChemDoodle.readMOL(molFile, 1);
cdcanvas.loadMolecule(molecule);
</script>
Author: Ove Daae Lampe
A library to quickly draw kernel density estimates from datasets stored in google spreadsheets
<script type="text/javascript" src="KDE.js"></script>
<body>
<div id="viscontainer" style="width:800px;height:600px;"></div>
<script type="text/javascript">
// Creating a new KDE requires only the id of the container
my_kde = new KDE( '#viscontainer' );
// Load data from a google spreadsheet key. Data must be public.
var key='0Ah8aKdOzkIVEdGlDZjc3VW1nenFrMnlfeVZfc0hLN0E';
my_kde.setGoogleData( key );
</script>
</body>
D3.js is a selection mechanism enabling the transformation of svg or dom objects to data visualizations. D3 focuses on efficient transofmations, or scene changes. D3.js shares the primary author with ProtoVis, Mike Bostock and as such has several similarities.
D3.js does not use the canvas class or WebGL, but utilizes inline SVG