Presentation is loading. Please wait.

Presentation is loading. Please wait.

Animation and Data Visualization in JavaScript by Kyle Scholz for The Ajax Experience October 24 th, 2006.

Similar presentations


Presentation on theme: "Animation and Data Visualization in JavaScript by Kyle Scholz for The Ajax Experience October 24 th, 2006."— Presentation transcript:

1 Animation and Data Visualization in JavaScript by Kyle Scholz for The Ajax Experience October 24 th, 2006

2 10/23/3006Animation and Data Visualization in JavaScript2 Overview Data Visualization and Animation Data Visualization Examples Popular Layout Algorithms Why JavaScript? / Challenges Developer’s Toolbox Tutorials Modeling Static Data Modeling Music Recommendations

3 In the Wild Data Visualization by Example

4 10/23/3006Animation and Data Visualization in JavaScript4

5 10/23/3006Animation and Data Visualization in JavaScript5

6 10/23/3006Animation and Data Visualization in JavaScript6

7 10/23/3006Animation and Data Visualization in JavaScript7

8 10/23/3006Animation and Data Visualization in JavaScript8

9 Resource Beautifully maintained catalog of “complex network” visualization.

10 Layout Generating Visualizations from Dynamic Data

11 10/23/3006Animation and Data Visualization in JavaScript11 Layout with Connected Graphs Graphs are visually accessible Convey meaning by visually expressing relationships with connections, colors, and proximity. Graphs are dynamic A single layout algorithm can service variable data sets.

12 10/23/3006Animation and Data Visualization in JavaScript12

13 10/23/3006Animation and Data Visualization in JavaScript13 Tree Layouts The Good Familiar metaphor – lot’s of data is structured in trees (hierarchies) Low computational complexity The Bad Organized using geometry – May result in a lot of overlap – Can balance. Can’t Support Circuits

14 10/23/3006Animation and Data Visualization in JavaScript14 So … What’s a Circuit?? A D E C B

15 10/23/3006Animation and Data Visualization in JavaScript15

16 10/23/3006Animation and Data Visualization in JavaScript16 Force Directed (or “Spring”) Layouts Based on a physical model: How electrons organize in space. Particles are the nodes in our graph. Attractive (“Spring”) Forces are our edges. Repulsive Forces exist between each node in the model.

17 10/23/3006Animation and Data Visualization in JavaScript17 Particles and Forces P2 P3 P4 P1 P Particle Spring Force Repulsive Force Key:

18 10/23/3006Animation and Data Visualization in JavaScript18 Why Force Directed Layouts? The Good Produce graphs with or without circuits Draw as few crossing edges as possible Neat to look at and fun to use Animated and interactive The Bad High Computational Complexity: On 2

19 10/23/3006Animation and Data Visualization in JavaScript19 Why Animate? Problem Rendering takes time. How do we know when we’re done? Complete data set may not be immediately available. Solution We show the user intermediate states so they can begin interacting sooner.

20 Why JavaScript?

21 10/23/3006Animation and Data Visualization in JavaScript21 Why use JavaScript? Flash, Java, ActiveX alternatives require plug-ins – Slow load time / Limited audience. HTML offers rich, familiar presentation elements. A JavaScript-powered graph can interact with the rest of your JavaScript application.

22 Challenges We aren’t seriously going to do this in JavaScript are we?

23 10/23/3006Animation and Data Visualization in JavaScript23 Performance We’re breaking from tradition, asking JavaScript to do some pretty intense stuff. Can JavaScript handle this? “JavaScript was designed for simple little web pages…” --(paraphrasing) IEBlog

24 10/23/3006Animation and Data Visualization in JavaScript24 JavaScript is 100X slower than Java? A frequently quoted statistic claims JavaScript is: –5000X slower than C –100X slower than Java Is this true? –Maybe, buy we’re comparing apples and oranges (and bananas) – Really depends on operations compared. But is it plausible? Absolutely.

25 10/23/3006Animation and Data Visualization in JavaScript25 Why is JavaScript Slow? Symbol lookup JavaScript uses late binding – Any time we use a variable, we have to search through the scope chain to find it. No types The meaning of an operator (like “+”) depends on whether arguments can be parsed as Strings or Numbers. Closures, Garbage Collection, etc…

26 10/23/3006Animation and Data Visualization in JavaScript26 Optimizing JavaScript Optimization is a huge topic, worthy of it’s own talk. For now, remember: –Before you start chasing milliseconds, optimize your algorithms. –Cache frequently used variables. –Keep variables local. Never store frequently used variables in the global scope.

27 JavaScript Visualization Toolbox …HTML doesn’t have a element

28 10/23/3006Animation and Data Visualization in JavaScript28 HTML and the DOM Sure, we can animate HTML! We’ll need to use images and hacky solutions to make shapes and lines. We control element positions using style attributes.

29 10/23/3006Animation and Data Visualization in JavaScript29 SVG == Awesome Draws lines and many shapes Access through the DOM –var shape = document.createElementNS(…) –shape.setAttribute( “x” 100 ) Prettier than HTML hacks Need plug-in to view in IE Partially implemented in Firefox and Opera Available in Safari soon

30 Tutorial #1 Using Timers to Animate HTML

31 10/23/3006Animation and Data Visualization in JavaScript31 Simplest Animation Tutorial Ever var sprite = document.createElement('div'); sprite.style.position = "absolute"; sprite.style.left = '0px'; sprite.style.top = '0px'; sprite.innerHTML = "MOVE"; document.body.appendChild( sprite ); var dirX = 1; function pos() { sprite.style.left = parseInt( sprite.style.left ) + dirX + 'px'; if ( parseInt(sprite.style.left) 300 ) { dirX *= -1; } setTimeout( pos, 1 ); } pos();

32 10/23/3006Animation and Data Visualization in JavaScript32

33 Tutorial #2 Animating XML Data with JSViz

34 10/23/3006Animation and Data Visualization in JavaScript34 What’s JSViz? A JavaScript library for generating animated connected graphs. Currently supports Tree and Force Directed layouts. Provides extendable architecture that can support additional layouts.

35 10/23/3006Animation and Data Visualization in JavaScript35 What does JSViz do? Implements a time-controlled model that dictates positions of nodes. Implements a view that controls display of nodes and relationships.

36 10/23/3006Animation and Data Visualization in JavaScript36 So What are We Building? A Force directed Graph that models the contents of an XML file.

37 10/23/3006Animation and Data Visualization in JavaScript37 XML Data (...continues)

38 10/23/3006Animation and Data Visualization in JavaScript38 Model of our Data

39 10/23/3006Animation and Data Visualization in JavaScript39 Create a Loader to process data into DataGraph Using JSViz Step 1: Make data accessible Loader Your Data DataGraph

40 10/23/3006Animation and Data Visualization in JavaScript40 XMLLoader.js var XMLLoader = function( dataGraph ) { this.init( dataGraph ); } XMLLoader.prototype = { init: function( dataGraph ) { this.http = new HTTP(); this.dataGraph = dataGraph; }, load: function( url ) { this.http.get( url, this, this.handle ); }

41 10/23/3006Animation and Data Visualization in JavaScript41 XMLLoader.js (2) handle: function( request ) { var xmlDoc = request.responseXML; var root = xmlDoc.getElementsByTagName("root")[0]; // add Root Node var rootNode = new DataGraphNode( true ); var mass = root.getAttribute("mass"); rootNode.mass = mass; var color = root.getAttribute("color"); rootNode.color = color; this.dataGraph.addNode( rootNode ); // add children this.branch( root, rootNode ); },

42 10/23/3006Animation and Data Visualization in JavaScript42 XMLLoader.js (3) branch: function( root, rootNode ) { var childNodes = root.childNodes; for( var i=0, l=childNodes.length; i

43 10/23/3006Animation and Data Visualization in JavaScript43 Using JSViz Step 2: Initialize Components DataGraph Particle Model ViewControl

44 10/23/3006Animation and Data Visualization in JavaScript44 Set up the HTML function init() {} html { filter: expression( document.execCommand( "BackgroundImageCache", false, true)); } body { margin: 0; padding: 0; }

45 10/23/3006Animation and Data Visualization in JavaScript45 Import Libraries

46 10/23/3006Animation and Data Visualization in JavaScript46 Get the Dimensions of the Page var FRAME_WIDTH; var FRAME_HEIGHT; if (document.all) { FRAME_WIDTH = document.body.offsetWidth - 5; FRAME_HEIGHT = document.documentElement.offsetHeight - 5; } else { FRAME_WIDTH = window.innerWidth - 5; FRAME_HEIGHT = window.innerHeight - 5; }

47 10/23/3006Animation and Data Visualization in JavaScript47 Initialize Components var view; if ( document.implementation.hasFeature( "org.w3c.dom.svg", '1.1') ) { view = new SVGGraphView( 0, 0, FRAME_WIDTH, FRAME_HEIGHT ); } else { view = new HTMLGraphView( 0, 0, FRAME_WIDTH, FRAME_HEIGHT ); } var particleModel = new ParticleModel( view ); particleModel.start(); var control = new Control( particleModel, view ); var dataGraph = new DataGraph(); var nodeHandler = new NodeHandler( dataGraph, particleModel, view, control ); dataGraph.subscribe( nodeHandler );

48 10/23/3006Animation and Data Visualization in JavaScript48 Initialize Components (2) Initialize our XMLLoader var xmlLoader = new XMLLoader( dataGraph ); xmlLoader.load( "nodes.xml" ); Also, we want to add particles to the model over time, enabling the model to organize under less entropy. var buildTimer = new Timer( 150 ); buildTimer.subscribe( nodeHandler ); buildTimer.start();

49 10/23/3006Animation and Data Visualization in JavaScript49 Using JSViz Step 3: Interpret Data into Model & View DataGraph Node Handler Particle Model View

50 10/23/3006Animation and Data Visualization in JavaScript50 Interpreting the Data var NodeHandler = function( dataGraph, particleModel, view, control ) { this.dataGraph = dataGraph; this.particleModel = particleModel; this.view = view; this.control = control; this.queue = new Array(); this['newDataGraphNode'] = function( dataGraphNode ) { this.enqueueNode( dataGraphNode ); } this['newDataGraphEdge'] = function( nodeA, nodeB ) { // Empty. We learn everything we need from // newDataGraphNode() }

51 10/23/3006Animation and Data Visualization in JavaScript51 Interpreting the Data (2) this['enqueueNode'] = function( dataGraphNode ) { this.queue.push( dataGraphNode ); } this['dequeueNode'] = function() { var node = this.queue.shift(); if ( node ) { this.addParticle( node ); } this.update = function() { this.dequeueNode(); }

52 10/23/3006Animation and Data Visualization in JavaScript52 Adding Particles to the Model this['addParticle'] = function( dataGraphNode ) { particle = this.particleModel.makeParticle( dataGraphNode.mass, 0, 0 ); // Make a “view node” in SVG if we can if ( document.implementation.hasFeature( "org.w3c.dom.svg", '1.1') ) { var bubble = document.createElementNS( "http://www.w3.org/2000/svg", "circle"); bubble.setAttribute('stroke', '#888888'); bubble.setAttribute('stroke-width', '.25px'); bubble.setAttribute('fill', dataGraphNode.color); bubble.setAttribute('r', 6 + 'px'); bubble.onmousedown = new EventHandler( control, control.handleMouseDownEvent, particle.id ) var viewNode = this.view.addNode(particle, bubble);

53 10/23/3006Animation and Data Visualization in JavaScript53 Adding Particles to the Model (2) } else { // Otherwise, make the view node in HTML var bubble = document.createElement( 'div' ); bubble.style.position = "absolute"; bubble.style.width = "12px"; bubble.style.height = "12px"; var color = dataGraphNode.color.replace( "#", "" ); bubble.style.backgroundImage = "url( /cgi-bin/bubble.pl?title=&r=12&pt=8&b=888888&c=" + color + ")"; bubble.innerHTML = ''; bubble.onmousedown = new EventHandler( control, control.handleMouseDownEvent, particle.id ) var viewNode = this.view.addNode(particle, bubble); }

54 10/23/3006Animation and Data Visualization in JavaScript54 Adding Particles to the Model (2) // Determine if this particle's position // should be fixed. if ( dataGraphNode.fixed ) { particle.fixed = true; } // Assign a random position to the particle. var rx = Math.random()*2-1; var ry = Math.random()*2-1; particle.positionX = rx; particle.positionY = ry;

55 10/23/3006Animation and Data Visualization in JavaScript55 Adding Particles to the Model (3) if ( dataGraphNode.parent ) { particle.positionX = dataGraphNode.parent.particle.positionX + rx; particle.positionY = dataGraphNode.parent.particle.positionY + ry; particleModel.makeSpring(particle, dataGraphNode.parent.particle,.2,.2, 10 ); var props; if ( document.implementation.hasFeature( "org.w3c.dom.svg", '1.1') ) { props = { 'stroke': dataGraphNode.parent.color, 'stroke-width': '2px', 'stroke-dasharray': '2,4‘ } } else { props = { 'pixelColor': dataGraphNode.color, 'pixelWidth':'2px', 'pixelHeight': '2px', 'pixels': 5 } } this.view.addEdge( particle, dataGraphNode.parent.particle, props ); }

56 10/23/3006Animation and Data Visualization in JavaScript56 Adding Particles to the Model (4) for ( var j=0, l=this.particleModel.particles.length; j

57 10/23/3006Animation and Data Visualization in JavaScript57 Model of our Data

58 Tutorial #3 Mashing Up Web Services with JSViz

59 10/23/3006Animation and Data Visualization in JavaScript59 So What are We Building? Let’s create an interactive application for finding music recommendations using Amazon.com’s Similarity API.

60 10/23/3006Animation and Data Visualization in JavaScript60

61 10/23/3006Animation and Data Visualization in JavaScript61 Getting Started We’re going to use Tutorial #2 as a base, so most of the work is done. First, we’ll need to make a Loader for Amazon data.

62 10/23/3006Animation and Data Visualization in JavaScript62 Amazon.js var Amazon = function( dataGraph, particleModel ) { this.init( dataGraph, particleModel ); } Amazon.prototype = { init: function( dataGraph, particleModel ) { this.http = new HTTP(); this.dataGraph = dataGraph; this.particleModel = particleModel; this.TRAVERSE_DEPTH = 1; this.MAX_SIMILAR = 6; this.MAX_NODES = 18; this.nodesByName = {}; this.nodesCount = 0; }

63 10/23/3006Animation and Data Visualization in JavaScript63 Amazon.js (2) search: function( productId, artist, title, image ) { document.getElementById('artistResults').style.display="none"; var node = new DataGraphNode( true, 2 ); node.label = productId; node.artist = artist; node.title = title; node.image = image; this.dataGraph.addNode( node ); this.nodesByName[productId] = node; this.getSimilar( productId, 0 ); },

64 10/23/3006Animation and Data Visualization in JavaScript64 Amazon.js (3) getSimilar: function( productId, ordinal ) { var similarityURL = "http://ecs.amazonaws.com..." + productId + “…"; this.http.get( PROXY_BASE + escape(similarityURL); this, this.handleSimilar, productId, ordinal ); },

65 10/23/3006Animation and Data Visualization in JavaScript65 Amazon.js (4) handleSimilar: function( request, parentId, ordinal ) { var xmlDoc = request.responseXML; var amzItem = xmlDoc.documentElement. getElementsByTagName(“Items")[0]. getElementsByTagName("Item"); for ( var i=0, l=amzItem.length; i

66 10/23/3006Animation and Data Visualization in JavaScript66 Amazon.js (5) var smallImage = amzItem[i]. getElementsByTagName("SmallImage")[0]; var smallImageURL = null; if ( smallImage ) { smallImageURL = getTextFromNode( smallImage.getElementsByTagName("URL")[0] ); } if ( !this.nodesByName[productId] ) { var node = new DataGraphNode( false, 1); node.label = productId; node.artist = getTextFromNode( amzArtist ); node.title = amzTitle; if ( smallImageURL ) { smallImageURL = 'http://kylescholz.com/cgi- bin/img_circle50.cgi?x=0&url=' + smallImageURL; }

67 10/23/3006Animation and Data Visualization in JavaScript67 Amazon.js (6) node.image = smallImageURL; node.addEdge( this.nodesByName[parentProductId], 1 ); this.dataGraph.addNode( node ); this.nodesCount++; this.nodesByName[productId] = node; if ( ordinal < this.TRAVERSE_DEPTH ) { this.getSimilar( productId, ordinal+1 ); } } else { var node = this.nodesByName[productId]; this.dataGraph.addEdge( node, this.nodesByName[parentProductId] ); }

68 10/23/3006Animation and Data Visualization in JavaScript68 Interpreting the Data We can start with the NodeHandler we used in Tutorial #2. We’ll add some additional functionality to queue up relationships.

69 10/23/3006Animation and Data Visualization in JavaScript69 Interpreting the Data (2) this.relationshipQueue = new Array(); this['newDataGraphEdge'] = function( nodeA, nodeB ) { this.enqueueRelationship( nodeA, nodeB ); } this['enqueueRelationship'] = function( nodeA, nodeB ) { this.relationshipQueue.push( {'nodeA': nodeA, 'nodeB': nodeB} ); } this['dequeueRelationship'] = function() { var edge = this.relationshipQueue.shift(); if ( edge ) { this.addSimilarity(.005, edge.nodeA, edge.nodeB ); } } this.update = function() { var nodes = this.dequeueNode(); if ( !nodes ) { this.dequeueRelationship(); } }

70 10/23/3006Animation and Data Visualization in JavaScript70 Interpreting the Data (3) this['addSimilarity'] = function( springConstant, nodeA, nodeB ) { particleModel.makeSpring( nodeA.particle, nodeB.particle, springConstant,.2, 80 ); var props; if ( document.implementation.hasFeature( "org.w3c.dom.svg", '1.1') ) { props = {'stroke': "#bbbbbb", 'stroke-width': '2px', 'stroke-dasharray': '2,8‘ } } else { props = {'pixelColor': "#aaaaaa", 'pixelWidth': '2px','pixelHeight': '2px', 'pixels': 15 } } this.view.addEdge( nodeA.particle, nodeB.particle, props ); }

71 10/23/3006Animation and Data Visualization in JavaScript71 Adding Particles to the Model addParticle() only differs in they way we construct the view.

72 10/23/3006Animation and Data Visualization in JavaScript72 Adding Particles to the Model (2) if ( dataGraphNode.image ) { var imgNode = document.createElement('div'); imgNode.style.position = "absolute"; imgNode.className = "artist"; imgNode.style.backgroundImage = "url('" + dataGraphNode.image + "')"; imgNode.innerHTML = '

' + dataGraphNode.artist + ' ' + dataGraphNode.title + ' '; imgNode.onmousedown = new EventHandler( control, control.handleMouseDownEvent, particle.id ) var viewNode = this.view.addNode( particle, imgNode, 25, 25 );

73 10/23/3006Animation and Data Visualization in JavaScript73 Adding Particles to the Model (3) // If no image is available, create a view node from // the available text. } else { var txtNode = document.createElement('div'); txtNode.style.width = "200px"; txtNode.style.position = "absolute"; txtNode.className = "artist"; txtNode.innerHTML = '

' + dataGraphNode.artist + ' ' + dataGraphNode.title + ' '; txtNode.onmousedown = new EventHandler( control, control.handleMouseDownEvent, particle.id ) var viewNode = this.view.addNode( particle, txtNode ); }

74 10/23/3006Animation and Data Visualization in JavaScript74

75 10/23/3006Animation and Data Visualization in JavaScript75 Extending this Example Use node size to convey meaning: “SalesRank” or other popularity Add extended information: Prices, checkout links, etc.

76 Resource JSViz and all other source code used in this presentation is available under Creative Commons license.

77 Photo Credits Photos in this presentation are used under a Creative Commons Attribution License. The original photo and license can be viewed at the URLs indicated. 13 – 16 – 24 –


Download ppt "Animation and Data Visualization in JavaScript by Kyle Scholz for The Ajax Experience October 24 th, 2006."

Similar presentations


Ads by Google