1218 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			1218 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html>
 | 
						|
<html lang="zh">
 | 
						|
<head>
 | 
						|
<link rel="stylesheet" href="visualPages.css">
 | 
						|
<title> Data Structure Visualization </title><meta charset="UTF-8">
 | 
						|
<link rel="shortcut icon" href="favicon.ico" />
 | 
						|
</head>
 | 
						|
<body>
 | 
						|
 | 
						|
<div class="container">
 | 
						|
<div class="header"><h1>Data Structure Visualizations</h1> </div>
 | 
						|
<div class="menu">
 | 
						|
<ul>
 | 
						|
<li> <a href="about.html">About</a> </li>
 | 
						|
<li> <a href="Algorithms.html">Algorithms</a> </li>
 | 
						|
<li> <a href="faq.html"> F.A.Q </a> </li>
 | 
						|
<li> <a href="bugfeature.html"> Known Bugs /<br>      Feature Requests  </a> </li>
 | 
						|
<li> <a href="java/visualization.html"> Java Version </a> </li>
 | 
						|
<li> <a href="flash.html">Flash Version </a> </li>
 | 
						|
<li> <a href="source.html">Create Your Own /<br>      Source Code</a> </li>
 | 
						|
<li> <a href="contact.html"> Contact </a> </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<br> <br>
 | 
						|
<div class="about">
 | 
						|
<a href="http://www.cs.usfca.edu/galles"> David Galles </a> <br>
 | 
						|
<a href="http://www.cs.usfca.edu"> Computer Science </a> <br>
 | 
						|
<a href="http://www.usfca.edu"> University of San Francisco </a>  
 | 
						|
</div>
 | 
						|
 | 
						|
</div>
 | 
						|
 | 
						|
<div class="content">
 | 
						|
 | 
						|
<h1>Source Code</h1>
 | 
						|
 | 
						|
You can download the complete source for the HTML5/Javascript version of the visualizations (both compressed and uncompressed) here:
 | 
						|
 | 
						|
<br>
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> <a href = "visualization1.4.tar.gz">visualization1.4.tar.gz</a>, <a href = "visualization1.4.tar">visualization.1.4.tar</a></li>
 | 
						|
<li> <a href = "visualization1.3.tar.gz">visualization1.3.tar.gz</a>, <a href = "visualization1.3.tar">visualization.1.3.tar</a></li>
 | 
						|
<li> <a href = "visualization1.2.tar.gz">visualization1.2.tar.gz</a>, <a href = "visualization1.2.tar">visualization.1.2.tar</a></li>
 | 
						|
<li> <a href = "visualization1.1.tar.gz">visualization1.1.tar.gz</a>, <a href = "visualization1.1.tar">visualization.1.1.tar</a> </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<br>
 | 
						|
 | 
						|
A few notes / warnings:
 | 
						|
 | 
						|
<ol>
 | 
						|
<li> <em>Do not</em> try to look at the code to understand the algorithms.  I have done one or two tricky 
 | 
						|
things to get the visualizations to work property that rather obscure the algorithms themselves.  Your
 | 
						|
favorte textbook, or even wikipedia, is a better bet for appropriate source code.</li>
 | 
						|
<li> Like all software projects, this one is a bit of a living thing -- it started life as a Java project, 
 | 
						|
was rewritten in ActionScript3 (that is, flash), and then ported to Javascript.  It was also my opportunity to 
 | 
						|
learn flash and javascript, so by the time I figured out the best way to do things, half of the software was
 | 
						|
already written.  I've done some going back to clean stuff up, but there is still a quite a lot of ugliness.
 | 
						|
<em>Next time</em> all my code will be pretty :).</li> 
 | 
						|
</ol>
 | 
						|
 | 
						|
 | 
						|
<h1>Visualization Creation Tutorial</h1>
 | 
						|
 | 
						|
To creeate a new visualization, you need to create a javascript file and an HTML file. The HTML file should
 | 
						|
 just be copied from a template, changing only one or two items (like the name of the javascript file).  
 | 
						|
 Examples of the HTML template and how to change it are at the end of this tutorial.
 | 
						|
 | 
						|
 In the javascript file, you will create a function (an object, really, but functions are objects in javascript) that:
 | 
						|
 | 
						|
<ol>
 | 
						|
<li> Creates any appropriate controls to control you visualization (inserting elements, deletig elements, etc)</li>
 | 
						|
<li> Creates callbacks for these controls that implement the visualizations.  The visualizations are implemented
 | 
						|
by sending an array of strings to the animation manager -- the animation manager will then implement the animation, and 
 | 
						|
handle all of the animation controls for you </li>
 | 
						|
<li> Listen for an undo event from the animation manager.  When an undo event is detected, roll back the last operation</li>
 | 
						|
</ol>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
<h2> Using Algorithm function </h2>
 | 
						|
 | 
						|
Creating the javascript function is stil farily complicated, even when using the rest of the library.
 | 
						|
 | 
						|
Many of the ugly details can be automated if your function "subclasses" the Algorithm function (located
 | 
						|
in <a href = "AlgorithmLibrary/Algorithm.js">AlgorithmLibrary/Algorithm.js</a> 
 | 
						|
(which is sort of a faux "class").  Consider the skeleton "MyAlgorithm" function included in the tarfile:
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> <a href = "AlgorithmLibrary/MyAlgorithm.js">AlgorithmLibrary/MyAlgorithm.js</a>
 | 
						|
</ul>
 | 
						|
 | 
						|
Looking at various pieces of the file in turn:
 | 
						|
<br>
 | 
						|
<br>
 | 
						|
Copyright:  Code is released under in a FreeBSD license.
 | 
						|
 | 
						|
<div  class = "code">
 | 
						|
<pre>
 | 
						|
// Copyright 2011 David Galles, University of San Francisco. All rights reserved.
 | 
						|
//
 | 
						|
// Redistribution and use in source and binary forms, with or without modification, are
 | 
						|
// permitted provided that the following conditions are met:
 | 
						|
//
 | 
						|
// 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
						|
// conditions and the following disclaimer.
 | 
						|
//
 | 
						|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
						|
// of conditions and the following disclaimer in the documentation and/or other materials
 | 
						|
// provided with the distribution.
 | 
						|
//
 | 
						|
// THIS SOFTWARE IS PROVIDED BY David Galles ``AS IS'' AND ANY EXPRESS OR IMPLIED
 | 
						|
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
						|
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
 | 
						|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
						|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
						|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 | 
						|
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
						|
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 | 
						|
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
//
 | 
						|
// The views and conclusions contained in the software and documentation are those of the
 | 
						|
// authors and should not be interpreted as representing official policies, either expressed
 | 
						|
// or implied, of the University of San Francisco
 | 
						|
</pre>
 | 
						|
</div>
 | 
						|
 | 
						|
Next, the algorithm definition.  We are doing a sort of "faked" inheritance within javascript.
 | 
						|
We define our function, set the prototype of our function to the prototype of our superclass,
 | 
						|
reset the constructor to be our own constructor, and then cache the superclass prototype,
 | 
						|
for simulating a java-style "super" call.  Notice that to make inheritance work well on 
 | 
						|
counstructors, we don't do anything in the main constructor function other than call an init
 | 
						|
function (that way we can have our init function call the init function of the superclass.
 | 
						|
Yes, this is a bit of a hack.)
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
function MyAlgorithm(am, w, h)
 | 
						|
{
 | 
						|
	this.init(am, w, h);
 | 
						|
}
 | 
						|
 | 
						|
MyAlgorithm.prototype = new Algorithm();
 | 
						|
MyAlgorithm.prototype.constructor = MyAlgorithm;
 | 
						|
MyAlgorithm.superclass = Algorithm.prototype;
 | 
						|
</pre>
 | 
						|
</div>
 | 
						|
 | 
						|
Next, we have our constructor.  In general, we will need to do the following
 | 
						|
in our counstructor:
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> Call the superclass counstructor.  Note the syntax, it's a little odd,
 | 
						|
but we are forcing javascript into an tradtional object-oriented paradigm, so it will
 | 
						|
complain a little at us. </li>
 | 
						|
<li> Add necessary controls<li>
 | 
						|
<li> Initialize our "Memory Manager".  For the most part, we will use a very 
 | 
						|
simple memory manager -- the old Pascal-style "Never free" memory manager. Start the 
 | 
						|
free list at 0, and then increment it every time you need a new piece of memory. </li>
 | 
						|
<li> Initialize any data structures we will be using</li>
 | 
						|
</li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
MyAlgorithm.prototype.init = function(am, w, h)
 | 
						|
{
 | 
						|
	// Call the unit function of our "superclass", which adds a couple of
 | 
						|
	// listeners, and sets up the undo stack
 | 
						|
	MyAlgorithm.superclass.init.call(this, am, w, h);
 | 
						|
	
 | 
						|
	this.addControls();
 | 
						|
	
 | 
						|
	// Useful for memory management
 | 
						|
	this.nextIndex = 0;
 | 
						|
 | 
						|
	// TODO:  Add any code necessary to set up your own algorithm.  Initialize data
 | 
						|
	// structures, etc.
 | 
						|
}
 | 
						|
</pre>
 | 
						|
</div>
 | 
						|
 | 
						|
Next we have the function to add controls.  There are several helper functions to add
 | 
						|
controls.  See the <a href = "AlgorithmLibrary/Algorithm.js">Algorithm.js</a> file for more 
 | 
						|
information on these helper functions.
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
MyAlgorithm.prototype.addControls =  function()
 | 
						|
{
 | 
						|
	this.controls = [];
 | 
						|
	
 | 
						|
    // Add any necessary controls for your algorithm.
 | 
						|
    //   There are libraries that help with text entry, buttons, check boxes, radio groups
 | 
						|
    //
 | 
						|
    // To add a button myButton:
 | 
						|
    //     this.mybytton = addControlToAlgorithmBar("Button", "MyButtonText");
 | 
						|
    //     this.mybytton.onclick = this.myCallback.bind(this);
 | 
						|
    //     this.controls.push(this.mybutton);
 | 
						|
    //   where myCallback is a method on this function that implemnts the callback
 | 
						|
    //
 | 
						|
    // To add a text field myField:
 | 
						|
    //    this.myField = addControlToAlgorithmBar("Text", "");
 | 
						|
    //    this.myField.onkeydown = this.returnSubmit(this.myField,  
 | 
						|
    //                                               this.anotherCallback.bind(this), // callback to make when return is pressed
 | 
						|
    //                                               maxFieldLen,                     // integer, max number of characters allowed in field
 | 
						|
    //                                               intOnly);                        // boolean, true of only digits can be entered.
 | 
						|
    //    this.controls.push(this.myField);
 | 
						|
    //
 | 
						|
    // To add a textbox:
 | 
						|
    //   	this.myCheckbox = addCheckboxToAlgorithmBar("Checkbox Label");
 | 
						|
    //      this.myCheckbox.onclick = this.checkboxCallback.bind(this);
 | 
						|
    //      this.controls.push(myCheckbox);
 | 
						|
    //
 | 
						|
    // To add a radio button group:
 | 
						|
    //	  this.radioButtonList = addRadioButtonGroupToAlgorithmBar(["radio button label 1", 
 | 
						|
    //                                                              "radio button label 2", 
 | 
						|
    //                                                              "radio button label 3"], 
 | 
						|
    //                                                             "MyButtonGroupName");
 | 
						|
    //    this.radioButtonList[0].onclick = this.firstRadioButtonCallback.bind(this);
 | 
						|
    //    this.controls.push(this.radioButtonList[0]);
 | 
						|
    //    this.radioButtonList[1].onclick = this.secondRadioButtonCallback.bind(this);
 | 
						|
    //    this.controls.push(this.radioButtonList[1]);
 | 
						|
    //    this.radioButtonList[2].onclick = this.thirdRadioButtonCallback.bind(this);
 | 
						|
    //    this.controls.push(this.radioButtonList[1]);
 | 
						|
    //
 | 
						|
    // Note that we are adding the controls to the controls array so that they can be enabled / disabled
 | 
						|
    // by the animation manager (see enableUI / disableUI below)
 | 
						|
}
 | 
						|
</pre>
 | 
						|
</div>
 | 
						|
 | 
						|
We will need to "override" the reset method.  Whenever the animation manager wants to
 | 
						|
undo an operation:
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> This reset method is called, which resets the state of your object to <em>exactly</em> how it was
 | 
						|
before any operations were performed
 | 
						|
<li> All of the operations up until the last one are replayed (though the animation information is
 | 
						|
thrown away </li>
 | 
						|
<li>We end up in the same state that we were in right before the last operation was done</li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
MyAlgorithm.prototype.reset = function()
 | 
						|
{
 | 
						|
	// Reset all of your data structures to *exactly* the state they have immediately after the init
 | 
						|
	// function is called.  This method is called whenever an "undo" is performed.  Your data
 | 
						|
	// structures are completely cleaned, and then all of the actions *up to but not including* the
 | 
						|
	// last action are then redone.  If you implement all of your actions through the "implementAction"
 | 
						|
	// method below, then all of this work is done for you in the Animation "superclass"
 | 
						|
	
 | 
						|
	// Reset the (very simple) memory manager
 | 
						|
	this.nextIndex = 0;
 | 
						|
}
 | 
						|
</pre>
 | 
						|
</div>
 | 
						|
 | 
						|
Callbacks, doing actual work
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
//////////////////////////////////////////////
 | 
						|
// Callbacks:
 | 
						|
//////////////////////////////////////////////
 | 
						|
//
 | 
						|
//   All of your callbacks should *not* do any work directly, but instead should go through the
 | 
						|
//   implement action command.  That way, undos are handled by ths system "behind the scenes"
 | 
						|
//
 | 
						|
//   A typical example:
 | 
						|
//
 | 
						|
//MyAlgorithm.prototype.insertCallback = function(event)
 | 
						|
//{
 | 
						|
//	// Get value to insert from textfield (created in addControls above)
 | 
						|
//	var insertedValue = this.insertField.value;
 | 
						|
//
 | 
						|
//  // If you want numbers to all have leading zeroes, you can add them like this:
 | 
						|
//	insertedValue = this.normalizeNumber(insertedValue, 4);
 | 
						|
//
 | 
						|
//  // Only do insertion if the text field is not empty ...
 | 
						|
//	if (insertedValue != "")
 | 
						|
//	{
 | 
						|
//		// Clear text field after operation
 | 
						|
//		this.insertField.value = "";
 | 
						|
//      // Do the actual work.  The function implementAction is defined in the algorithm superclass
 | 
						|
//		this.implementAction(this.insertElement.bind(this), insertedValue);
 | 
						|
//	}
 | 
						|
//}
 | 
						|
//  Note that implementAction takes as parameters a function and an argument, and then calls that
 | 
						|
//  function using that argument (while also storing the function/argument pair for future undos)
 | 
						|
 | 
						|
//////////////////////////////////////////////
 | 
						|
// Doing actual work
 | 
						|
//////////////////////////////////////////////
 | 
						|
//   The functions that are called by implementAction (like insertElement in the comments above) need to:
 | 
						|
//
 | 
						|
//      1. Create an array of strings that represent commands to give to the animation manager
 | 
						|
//      2. Return this array of commands
 | 
						|
//
 | 
						|
//    We strongly recommend that you use the this.cmd function, which is a handy utility function that
 | 
						|
//    appends commands onto the instance variable this.commands
 | 
						|
//
 | 
						|
//    A simple example:
 | 
						|
//
 | 
						|
//MyAlgorithm.simpleAction(input)
 | 
						|
//{
 | 
						|
//	this.commands = [];  // Empty out our commands variable, so it isn't corrupted by previous actions
 | 
						|
//
 | 
						|
//	// Get a new memory ID for the circle that we are going to create
 | 
						|
//	var circleID = nextIndex++;
 | 
						|
//	var circleX = 50;
 | 
						|
//	var circleY = 50;
 | 
						|
//	
 | 
						|
//	// Create a circle
 | 
						|
//	this.cmd("CreateCircle", circleID, "Label",  circleX, circleY);
 | 
						|
//	circleX = 100; 
 | 
						|
//	// Move the circle
 | 
						|
//	this.cmd("Move", circleID, circleX, circleY);
 | 
						|
//	// First Animation step done
 | 
						|
//	this.cmd("Step");
 | 
						|
//	circleX = 50; 
 | 
						|
//	circleY = 100; 
 | 
						|
//	// Move the circle again
 | 
						|
//	this.cmd("Move", circleID, circleX, circleY);
 | 
						|
//	// Next Animation step done
 | 
						|
//	this.cmd("Step");
 | 
						|
//	// Return the commands that were generated by the "cmd" calls:
 | 
						|
//	return this.commands;
 | 
						|
//}
 | 
						|
 | 
						|
</pre>
 | 
						|
</div>
 | 
						|
 | 
						|
 | 
						|
Enabling, disabling UI
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
// Called by our superclass when we get an animation started event -- need to wait for the
 | 
						|
// event to finish before we start doing anything
 | 
						|
MyAlgorithm.prototype.disableUI = function(event)
 | 
						|
{
 | 
						|
	for (var i = 0; i < this.controls.length; i++)
 | 
						|
	{
 | 
						|
		this.controls[i].disabled = true;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Called by our superclass when we get an animation completed event -- we can
 | 
						|
/// now interact again.
 | 
						|
MyAlgorithm.prototype.enableUI = function(event)
 | 
						|
{
 | 
						|
	for (var i = 0; i < this.controls.length; i++)
 | 
						|
	{
 | 
						|
		this.controls[i].disabled = true;
 | 
						|
	}
 | 
						|
}
 | 
						|
</pre>
 | 
						|
</div>
 | 
						|
 | 
						|
Script to start everything
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
// Script to start up your function, called from the webapge:
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
var currentAlg;
 | 
						|
 | 
						|
function init()
 | 
						|
{
 | 
						|
	var animManag = initCanvas();
 | 
						|
	currentAlg = new MyAlgorithm(animManag, canvas.width, canvas.height);
 | 
						|
	
 | 
						|
}
 | 
						|
</pre>
 | 
						|
</div> 
 | 
						|
 | 
						|
<h2> Animation Commands </h2>
 | 
						|
 | 
						|
The commands that we give to the animatino manager are a list (array) of strings.  Each string starts with
 | 
						|
the name of the command (case-insensitive) followed by a list of arguments, separated by the token <;>.
 | 
						|
The first argument of (almost) every command is the ID of the object you want to create or access.  So, the string
 | 
						|
to Move element 37 to position (100, 120) would be:
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> "Move<;>37<;>100<;>120"</li>
 | 
						|
</ul>
 | 
						|
Commands can be separated into two groups:  Commands that create animated objects, and commands
 | 
						|
that manipulate previously created objects. 
 | 
						|
 | 
						|
<h3> Object Creation and Deletion Commands </h3>
 | 
						|
 | 
						|
Object creation commands take as a first argument an integer
 | 
						|
representing the index of the object to create.  This integer must <em>not</em> be the same as another
 | 
						|
object that is currently active in the system (though you can reuse numbers once the objects have been 
 | 
						|
deleted).  Like all commands, the creation commands have some required and some optional parameters.
 | 
						|
 | 
						|
<br>
 | 
						|
<ul>
 | 
						|
<li> CreateCircle: objectID, label, [initial_x, initial_y] </li>
 | 
						|
<ul>
 | 
						|
<li> objectID:  Non-negative integer that represents the ID of this object.  Must be different from any
 | 
						|
ID currently active.  Should be as small as posslbe for better performance.</li>
 | 
						|
<li> label: the label that appears in the middle of the circle.  It may contain end of line (\n) characters,
 | 
						|
which allows you to place a multi-line label in the circle.  Labels are centered in circles. </li>
 | 
						|
<li> initial_x: (optional, defaults to 0) the initial x position of the circle</li>
 | 
						|
<li> initial_y: (optional, defaults to 0) the initial u position of the circle</li>
 | 
						|
</ul>
 | 
						|
<li> CreateRectange: objectID, label, width, height, [initial_x, initial_y, xJustify, yJustufy, backgroundColor, foregroundColor]</li>
 | 
						|
<ul>
 | 
						|
<li> objectID:  Non-negative integer that represents the ID of this object.  Must be different from any
 | 
						|
ID currently active.  Should be as small as posslbe for better performance.</li>
 | 
						|
 | 
						|
<li> label: the label that appears in the middle of the rectangle.  It may contain end of line (\n) characters,
 | 
						|
which allows you to place a multi-line label in the rectangle.  Labels are centered in rectangles. </li>
 | 
						|
<li> width:  The width of the rectangle, in pixels </li>
 | 
						|
<li> height: The height of the rectangle, in pixels </li>
 | 
						|
<li> initial_x: (optional, defaults to 0) the initial x position of the rectangle</li>
 | 
						|
<li> initial_y: (optional, defaults to 0) the initial u position of the rectangle</li>
 | 
						|
<li> xJustify: (optional, defaults to "center").  One of "center", "left", "right" -- If the rectangle is at location (x, y), 
 | 
						|
does x stand for the left, center, or right of the rectangle </li>
 | 
						|
<li> yJustify: (optional, defaults to "center").  One of "center", "top", "bottom" -- If the rectangle is at location (x,y0 does
 | 
						|
 y stand for the top, center, or bottom of the rectangle </li>
 | 
						|
 <li> foregroundColor:  The initial color of the foregorund of the rectangle, using string representations of HTML colors ("#FF0000" for red, "#00FF00" for green,
 | 
						|
 and so on).  Defaults to black
 | 
						|
 <li> backgroundColor:  The initial color of the background of the rectangle, using HTML colors (#FF0000 for red, #00FF00 for green,
 | 
						|
 and so on).  Defaults to white.
 | 
						|
</ul>    
 | 
						|
 | 
						|
<li> CreateHighlightCircle: objectID, color, [initial_x, initial_y, radius] <br>
 | 
						|
A highlight circle is much like a standard circle, except that it has no label, and no background color, so that
 | 
						|
it does not obscure other objects like a circle does.
 | 
						|
<ul>
 | 
						|
<li> objectID:  Non-negative integer that represents the ID of this object.  Must be different from any
 | 
						|
ID currently active.  Should be as small as posslbe for better performance.</li>
 | 
						|
 <li> color:  The initial color of the circle, using HTML colors ("#FF0000" for red, "#00FF00" for green,
 | 
						|
 and so on)
 | 
						|
 | 
						|
<li> initial_x: (optional, defaults to 0) the initial x position of the circle</li>
 | 
						|
<li> initial_y: (optional, defaults to 0) the initial u position of the circle</li>
 | 
						|
 <li> radius: (optional, defaults to 20)  The radius of the circle.
 | 
						|
 | 
						|
</ul>
 | 
						|
<li> CreateLabel: objectID, label, [initial_x, initial_x, centered] </li>
 | 
						|
<ul>
 | 
						|
<li> objectID:  Non-negative integer that represents the ID of this object.  Must be different from any
 | 
						|
ID currently active.  Should be as small as posslbe for better performance.</li>
 | 
						|
<li> label: the text of the label.  It may contain end of line (\n) characters,
 | 
						|
which allows you to place a multi-line labels. </li>
 | 
						|
<li> initial_x: (optional, defaults to 0) the initial x position of the label</li>
 | 
						|
<li> initial_y: (optional, defaults to 0) the initial y position of the label</li>
 | 
						|
<li> centered: (optional, defaults to true) true or 1 if the label should be centered, false or 0 if it should not.</li>
 | 
						|
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> CreateLinkedList: objectID, label, width, height, [initial_x, initial_y, linkPercent, verticalOrientation, linkPosEnd, numLabels]
 | 
						|
<ul>
 | 
						|
<li> objectID:  Non-negative integer that represents the ID of this object.  Must be different from any
 | 
						|
ID currently active.  Should be as small as posslbe for better performance.</li>
 | 
						|
<li> label:  The label inside this linked list element (or the first label, if there are more than one)
 | 
						|
<li> width:  The width of the linked list element, in pixels </li>
 | 
						|
<li> height: The height of the linked list element, in pixels </li>
 | 
						|
<li> initial_x: (optional, defaults to 0) the initial x position of the linked list element</li>
 | 
						|
<li> initial_y: (optional, defaults to 0) the initial y position of the linked list element</li>
 | 
						|
<li> linkPercent: (optional, defaults to 0.25) The percentage of the linked list element that the outgoing pointer takes up. </li>
 | 
						|
<li> verticalOrientation: (optional, defaults to true).  Should the linked list element be vertial (true) or horizontal (false) </li>
 | 
						|
<li> linkPosEnd: (optional, defaults to false).  Should the poiner appear at the bottom or left of the linked list element (true), or the 
 | 
						|
top or right of the linked list element (false) </li>
 | 
						|
<li> numLabels:  (optional, defaults to 1).  The number of labels that the linked lists element can hold.  See the adjacency 
 | 
						|
list implementat of a  graph visualization  for an example of a linked list element with more than 1 label.
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> CreateBTreeNode: objectID, widthPerLabel, height, numLabels, inital_x, initial_y, backgroundColor, foregroundColor</li>
 | 
						|
Somewhat special-purpose animated object created for B-Trees.   Single rectangle containing any number of labels, with no dividing
 | 
						|
lines between the labels.  Edges can be attached between each label, and to the left of the leftmost label, and to the right of the rightmost
 | 
						|
label.  See the BTree and B+ Tree visualizations for examples.
 | 
						|
<ul>
 | 
						|
<li> objectID:  Non-negative integer that represents the ID of this object.  Must be different from any
 | 
						|
ID currently active.  Should be as small as posslbe for better performance.</li>
 | 
						|
<li> widthPerLabel:  The width of the B-Tree node is the number of labels * the width per label.  Value is in pixels.</li>
 | 
						|
<li> height:  Height of the B-Tree node in pixels</li>
 | 
						|
<li> numLabels:  The number of labels in the BTree node. </li>
 | 
						|
<li> initial_x:  The initial x position of the B-Tree node </li>
 | 
						|
<li> initial_y:  The initial y position of the B-Tree node </li>
 | 
						|
 <li> backgroundColor:  The initial color of the background of the rectangle, using HTML colors (#FF0000 for red, #00FF00 for green,
 | 
						|
 and so on) </li>
 | 
						|
 <li> backgroundColor:  The initial color of the forground of the rectangle, using HTML colors (#FF0000 for red, #00FF00 for green,
 | 
						|
 and so on) </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> Delete: objectID </li>
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to delete.  All edges incident on this object will be removed. (If the delete is undone, then 
 | 
						|
all such edges will be restored).  Once an Animated Element has been deleted, its ID is free to be used again. 
 | 
						|
Note that overly complicated ID management (which is really memory management, since IDs are just indicies into a
 | 
						|
"memory array" of active animated objects) is not necessarily recommended, since it can lead to some subtle bugs.
 | 
						|
</ul>
 | 
						|
</ul>
 | 
						|
 | 
						|
Note that creation of an object using an objectID that already is in use will throw an exception.
 | 
						|
Deleting an ID that is not currently in use will also throw an exception.
 | 
						|
 | 
						|
<h3> Object Manipulation Commands </h3>
 | 
						|
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> Move: objectID, toX, toY</li>
 | 
						|
Move the object smoothly over the next step from the current position to 
 | 
						|
the new position
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to move.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> toX:  The new X location to move to </li>
 | 
						|
<li> toY:  The new Y location to move to </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> SetPosition: objectID, toX, toY</li>
 | 
						|
Move the object immediately to the new position at the beginning of the next step
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to move.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> toX:  The new X location to move to </li>
 | 
						|
<li> toY:  The new Y location to move to </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
<li> SetForegroundColor: objectID, color</li>
 | 
						|
Sets the foreground color (outline color and label color) of an object.  Note that if
 | 
						|
an object has several labels this will set the color of <em>all</em> labels.
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> color:  New foreground color (string representing HTML color, like "#ff0000")</li>
 | 
						|
</ul>
 | 
						|
 | 
						|
 | 
						|
<li> SetBackgroundColor: objectID, color</li>
 | 
						|
Sets the background color of current object.  Note that if
 | 
						|
an object has several labels this will set the color of an object.
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exist, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> color:  New background color</li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> SetHighlight: objectID, highlightVal</li>
 | 
						|
Mark an object as either highlighted or unhighlighted, based on the value of highlightVal.  
 | 
						|
Objects that are highlighted will pulse red.  Any object can be highlighted (thought labels
 | 
						|
are slightly harder to read when highlighted)  Note that if an object is left highlighted
 | 
						|
after an animation is ended, it will not pulse until the animation starts again.  Edges
 | 
						|
can be highlighted using the highlight edge command. 
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> highlightVal:  1 or true, turn on highlighting.  0 or false, turn off highlighting.</li>
 | 
						|
</ul>
 | 
						|
 | 
						|
 | 
						|
<li> SetText: objectID, newText, [textIndex]</li>
 | 
						|
Sets the value of the label associated with the object (the printing withing a circle, for instance). 
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> newText: The new text of the label </li>
 | 
						|
<li> textIndex: (optional, defaults to 0) Index of the text label to change.  Only used in
 | 
						|
objects that have more than one text label (B-Tree nodes, Linked List nodes).  If the object does
 | 
						|
not support multiple labels, this is ignored.  </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> SetAlpha: objectID</li>
 | 
						|
Sets the alpha (transparency) of the object. 0 is completely transparent, 1 is completely opaque.  Works for all objects.
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown. </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
 | 
						|
<li> SetHeight: objectID, newHeight</li>
 | 
						|
Sets the height (in pixels) of the object.
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> newHeight:  The new height of the object. </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
 | 
						|
<li> SetWidth: objectID, newWIdth</li>
 | 
						|
Sets the width (in pixels) of the object.
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> newWidth:  The new width of the object. </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
<li> SetTextColor: objectID, newColor, [textIndex]</li>
 | 
						|
Sets the color of the label associated with the object
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> newColor:  The new color to set.  As with all colors, should be a html color string </li>
 | 
						|
<li> textIndex:  (optional, defaults to 0)  If the object contain multiple labels (such as a linked-list node,
 | 
						|
or a B-Tree node) determine which label to change the color of.  If the object only has one label, this parameter 
 | 
						|
is ignored. </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
 | 
						|
<li> SetNull: objectID, nullValue</li>
 | 
						|
Currently only used for linked-list elements.  Should the area set aside for the pointer in the
 | 
						|
linked list object be drawn as a null pointer (slash through the field)?   This should probably
 | 
						|
be automated (draw the slash if and only if the node is not connected to anything), but for now
 | 
						|
this must be done manually.
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> nullValue:  0 or false for do not draw the slash, 1 or true for draw the slash. </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
 | 
						|
<li> SetNumElements: objectID, numElements</li>
 | 
						|
Currently only used for B-Tree nodes.  Changes the number of labels stored in this B-tree node.
 | 
						|
Should probably be extended to at least Linked-list nodes.
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> numElements:  integer, the number of elements this B-Tree node should have </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> AlignRight: object1ID, object2ID</li>
 | 
						|
Align object1 so that it is immediately to the right of object2.  Very handy for lining up labels
 | 
						|
(where you don't necessarily know the width of the label), but can be used with any two objects.
 | 
						|
<ul>
 | 
						|
<li> object1ID:  The ID of the object to move.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> object2ID:  The ID of the object used to align object1.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> AlignLeft: object1ID, object2ID</li>
 | 
						|
Align object1 so that it is immediately to the left of object2.  Very handy for lining up labels
 | 
						|
(where you don't necessarily know the width of the label), but can be used with any two objects.
 | 
						|
<ul>
 | 
						|
<li> object1ID:  The ID of the object to move.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> object2ID:  The ID of the object used to align object1.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> AlignTop: object1ID, object2ID</li>
 | 
						|
Align object1 so that it is immediately on top of of object2.  Very handy for lining up labels
 | 
						|
(where you don't necessarily know the width of the label), but can be used with any two objects.
 | 
						|
<ul>
 | 
						|
<li> object1ID:  The ID of the object to move.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> object2ID:  The ID of the object used to align object1.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> AlignBottom: object1ID, object2ID</li>
 | 
						|
Align object1 so that it is immediately below object2.  Very handy for lining up labels
 | 
						|
(where you don't necessarily know the width of the label), but can be used with any two objects.
 | 
						|
<ul>
 | 
						|
<li> object1ID:  The ID of the object to move.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> object2ID:  The ID of the object used to align object1.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
</ul>
 | 
						|
 | 
						|
<h3> Edge Manipulation Commands </h3>
 | 
						|
 | 
						|
Edges are manipulated by giving the two objects associated with the edge.  While edges
 | 
						|
can be graphically directed or undirected, all edges under the hood have a direction,
 | 
						|
which is the direction that they were given when the edge was created.   There can
 | 
						|
only be <em> one </em> edge from any object to any other object (though there can be 
 | 
						|
an edge from object1 to object2, and a different edge from object2 to object1.)  Edges
 | 
						|
are always referred to by two IDs - the objectID of the "from" object, followed by the
 | 
						|
objectID of the "to" object.  Any object can be connected to any other object.
 | 
						|
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> Connect: fromID, toID, [linkColor, curve, directed, label, anchorPosition] </li>
 | 
						|
<ul>,
 | 
						|
<li> fromID:  The ID of the object at the tail of the new edge </li>
 | 
						|
<li> toID:  The ID of the object at the head of the new edge </li>
 | 
						|
<li> linkColor: (optional, defaults to "#000000") The color of the edge </li>
 | 
						|
<li> linkColor: (optional, defaults to false) true for a diected edge, false for an undirected edge </li>
 | 
						|
<li> curve:  (optional, defaults to 0.0) The "curviness" of the edge.  0.0 is perfectly straight, positive values
 | 
						|
arc to the right, negative values arc to the left. </li>
 | 
						|
<li> directed (optional, defaults to true).  True if the edge is directed, false if the edge is undirected </li>
 | 
						|
<li> label (optional, defaults to "").  The label that appears along the edge (useful for things like edge
 | 
						|
costs in graphs) </li>
 | 
						|
<li> anchorPosition (optional, defaults to 0) If the edge could have more than one attachment
 | 
						|
postion at the "from" node, (currently only used for B-Tree nodes, but could well be expanded to things like
 | 
						|
doubly-linked lists) the index of the attachment position to use. Ignored for animated objects that
 | 
						|
do not have multiple attachment positions </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> Disconnect: fromID, toID</li>
 | 
						|
Removes an edge between two elements.  If there is no edge, then this operation is a no-op. 
 | 
						|
<ul>
 | 
						|
<li> fromID: The ID of the "From" direction of the edge </li>
 | 
						|
<li> toID:  The ID of the "To" direction of the edge </li>
 | 
						|
</ul>
 | 
						|
Note that even "undirected" edges have a "from" and a "to" -- determined by how the
 | 
						|
edge was created using the Connect command.
 | 
						|
 | 
						|
<li> SetAlpha: objectID</li>
 | 
						|
Sets the alpha (transparency) of the object. 0 is completely transparent, 1 is completely opaque
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
<li> SetEdgeHighlight: fromID, toID, highlightVal</li>
 | 
						|
Mark an edge as either highlighted or unhighlighted, based on the value of highlightVal.  
 | 
						|
Edges that are highlighted will pulse red. 
 | 
						|
<ul>
 | 
						|
<li> fromID: The ID of the "From" direction of the edge </li>
 | 
						|
<li> toID:  The ID of the "To" direction of the edge </li>
 | 
						|
<li> higlightVal:  0 or false, turn of higlighting.  1 or true, turn on highlighting.</li>
 | 
						|
</ul>
 | 
						|
 | 
						|
</ul>
 | 
						|
 | 
						|
<h3> Special Commands </h3>
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> Step: <No parameters> </li>
 | 
						|
The step command allows you to keep everything from happening at once.  The way that most
 | 
						|
animations will work is that you will create a group of objects, then do a step, then do
 | 
						|
some movements, then do a step, then do more movements, then do a step, and so on.  All
 | 
						|
commands that appear between adjacent steps will happen simultaneously.  Each step represents where
 | 
						|
the animation will pause when it is in single-step mode.
 | 
						|
 | 
						|
 | 
						|
<li> SetLayer objectID, newLayer </li>
 | 
						|
Sets the layer of the object.  All objects default to layer 0, and the "shown" layer always defaults
 | 
						|
to 0.  You can change the layers of different objects, and then change the list of which layers
 | 
						|
are currently shown, to show or hide objects dynamically.  (This is often useful for allowing the
 | 
						|
user to show or hide information, or to alternate between different versions of a representation).
 | 
						|
An object will only appear if its layer is one of the layers listed to be shown.  An edge will
 | 
						|
only appear of each of the objects that it connect are to be shown.  While commands cannot be executed
 | 
						|
while an animation is running, the global set of visible layers can be changed while an animation is running
 | 
						|
<ul>
 | 
						|
<li> objectID:  The ID of the object to modify.  The object must exists, or an exception will be
 | 
						|
thrown </li>
 | 
						|
<li> layer:  The new layer for this object.  Each object must live in one and only one layer
 | 
						|
(though any combination of layers can be shown at any given time) </li>
 | 
						|
</ul> 
 | 
						|
</ul>
 | 
						|
 | 
						|
<h2> Simple Stack Example </h2>
 | 
						|
 | 
						|
Everything make sense so far?  Time for a simple, complete example. A simple stack visualization can be found at:
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> <a href = "AlgorithmLibrary/SimpleStack.js">AlgorithmLibrary/SimpleStack.js</a>
 | 
						|
<li> <a href = "SimpleStack.html"> See the the visualization in action </a>
 | 
						|
</ul>
 | 
						|
 | 
						|
Looking at the complete SimpleStack.js file in its entirety:
 | 
						|
<br><br>
 | 
						|
All code released under a FreeBSD license
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
// Copyright 2011 David Galles, University of San Francisco. All rights reserved.
 | 
						|
//
 | 
						|
// Redistribution and use in source and binary forms, with or without modification, are
 | 
						|
// permitted provided that the following conditions are met:
 | 
						|
//
 | 
						|
// 1. Redistributions of source code must retain the above copyright notice, this list of
 | 
						|
// conditions and the following disclaimer.
 | 
						|
//
 | 
						|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
						|
// of conditions and the following disclaimer in the documentation and/or other materials
 | 
						|
// provided with the distribution.
 | 
						|
//
 | 
						|
// THIS SOFTWARE IS PROVIDED BY David Galles ``AS IS'' AND ANY EXPRESS OR IMPLIED
 | 
						|
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
						|
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
 | 
						|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
						|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
						|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 | 
						|
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
						|
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 | 
						|
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
//
 | 
						|
// The views and conclusions contained in the software and documentation are those of the
 | 
						|
// authors and should not be interpreted as representing official policies, either expressed
 | 
						|
// or implied, of the University of San Francisco
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
 | 
						|
Next up is the Initial setup.  The first several lines of any visualization javascript will look like this, with
 | 
						|
SimpleStack replaced by whatever function you are writing
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
function SimpleStack(am, w, h)
 | 
						|
{
 | 
						|
	this.init(am, w, h);
 | 
						|
}
 | 
						|
 | 
						|
SimpleStack.prototype = new Algorithm();
 | 
						|
SimpleStack.prototype.constructor = SimpleStack;
 | 
						|
SimpleStack.superclass = Algorithm.prototype;
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
The next items in the file are some constants.  We placed them in the function's namespace
 | 
						|
to avoid symbol clashes:
 | 
						|
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
SimpleStack.ELEMENT_WIDTH = 30;
 | 
						|
SimpleStack.ELEMENT_HEIGHT = 30;
 | 
						|
SimpleStack.INSERT_X = 30;
 | 
						|
SimpleStack.INSERT_Y = 30;
 | 
						|
SimpleStack.STARTING_X = 30;
 | 
						|
SimpleStack.STARTING_Y = 100;
 | 
						|
SimpleStack.FOREGROUND_COLOR = "#000055"
 | 
						|
SimpleStack.BACKGROUND_COLOR = "#AAAAFF"
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
Next up is the constructor.  Technically, the constructor was first:
 | 
						|
 | 
						|
<pre>
 | 
						|
function SimpleStack( ...
 | 
						|
</pre>
 | 
						|
 | 
						|
However, all of the <em>work</em> of the constructor is done in the init function -- that
 | 
						|
way constructors of subclass can effectively call the constructors of their superclasses.
 | 
						|
For the init function in this case, we need to do very little work.  In this simple example
 | 
						|
we are not adding any elements to the canvas at load time.  All we need to do is set up our own
 | 
						|
internal data structures.  We are keeping track of two arrays -- an array that stores the actual 
 | 
						|
stack (stackValues), and an array that stores the objectIDs of the elements of the stack (stackID)
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
SimpleStack.prototype.init = function(am, w, h)
 | 
						|
{
 | 
						|
	// Call the unit function of our "superclass", which adds a couple of
 | 
						|
	// listeners, and sets up the undo stack
 | 
						|
	SimpleStack.superclass.init.call(this, am, w, h);
 | 
						|
	
 | 
						|
	this.addControls();
 | 
						|
	
 | 
						|
	// Useful for memory management
 | 
						|
	this.nextIndex = 0;
 | 
						|
 | 
						|
	this.stackID = [];
 | 
						|
	this.stackValues = [];
 | 
						|
	
 | 
						|
	this.stackTop = 0;
 | 
						|
}
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
Next up is the method to add algorithm controls and callbacks.  The tricky bit here is that we can't do something like:
 | 
						|
 | 
						|
<pre>
 | 
						|
this.popButton.onclick = this.popCallback
 | 
						|
</pre>
 | 
						|
 | 
						|
to add our callbacks.  Why not?  This would pass in the proper function, but <em>not</em> the 
 | 
						|
proper <em>contex</em> -- essentially, it would be passing a pointer to the code of the function,
 | 
						|
without saving the "this" pointer.  So we need to bind the "this" pointer to our function before
 | 
						|
we store it.  
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
SimpleStack.prototype.addControls =  function()
 | 
						|
{
 | 
						|
	this.controls = [];
 | 
						|
 | 
						|
	
 | 
						|
    this.pushField = addControlToAlgorithmBar("Text", "");
 | 
						|
    this.pushField.onkeydown = this.returnSubmit(this.pushField,  
 | 
						|
                                               this.pushCallback.bind(this), // callback to make when return is pressed
 | 
						|
                                               4,                           // integer, max number of characters allowed in field
 | 
						|
                                               false);                      // boolean, true of only digits can be entered.
 | 
						|
	this.controls.push(this.pushField);
 | 
						|
	
 | 
						|
	this.pushButton = addControlToAlgorithmBar("Button", "Push");
 | 
						|
	this.pushButton.onclick = this.pushCallback.bind(this);
 | 
						|
	this.controls.push(this.pushButton);
 | 
						|
	
 | 
						|
	this.popButton = addControlToAlgorithmBar("Button", "Pop");
 | 
						|
	this.popButton.onclick = this.popCallback.bind(this);
 | 
						|
	this.controls.push(this.popButton);	
 | 
						|
}
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
As a side note, here's the code for the bind function, located in CustomEvents.js
 | 
						|
 | 
						|
<pre>
 | 
						|
Function.prototype.bind = function() {
 | 
						|
	var _function = this;
 | 
						|
	
 | 
						|
	var args = Array.prototype.slice.call(arguments);
 | 
						|
	var scope = args.shift()
 | 
						|
	return function() {
 | 
						|
		for (var i = 0; i < arguments.length; i++)
 | 
						|
		{
 | 
						|
			args.push(arguments[i]);
 | 
						|
		}
 | 
						|
		return _function.apply(scope, args);
 | 
						|
	}
 | 
						|
}
 | 
						|
</pre>
 | 
						|
 | 
						|
Moving on ... Next up is the reset function.  <em>All visualizations must implement the reset method</em>.  The reset 
 | 
						|
method needs to restore <em>all</em> of our variables to the state that they were in right after the call to init.
 | 
						|
In our case, we only have 2 variables of importance.  We could have recreated the arrays stackID and stackValues, but
 | 
						|
that is not necessary in this case, since we don't care about the current values in those arrays -- we will write over any 
 | 
						|
value before we read it, once the stack top is 0.
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
SimpleStack.prototype.reset = function()
 | 
						|
{
 | 
						|
	// Reset the (very simple) memory manager.
 | 
						|
	//  NOTE:  If we had added a number of objects to the scene *before* any user
 | 
						|
	//         input, then we would want to set this to the appropriate value based
 | 
						|
	//         on objects added to the scene before the first user input
 | 
						|
	this.nextIndex = 0;
 | 
						|
	
 | 
						|
	// Reset our data structure.  (Simple in this case)
 | 
						|
	this.stackTop = 0;
 | 
						|
}
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
Next up, the callbacks.  Note that we don't do any action directly on a callback -- instead, we use the
 | 
						|
implementAction method, which takes a bound function (using the bind method) and a parameter, and them
 | 
						|
calls that function using that parameter.  implementAction also saves a list of all actions that have been
 | 
						|
performed, so that undo will work nicely.
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
SimpleStack.prototype.pushCallback = function()
 | 
						|
{
 | 
						|
	var pushedValue = this.pushField.value;
 | 
						|
	
 | 
						|
	if (pushedValue != "")
 | 
						|
	{
 | 
						|
		this.pushField.value = "";
 | 
						|
		this.implementAction(this.push.bind(this), pushedValue);
 | 
						|
	}
 | 
						|
	
 | 
						|
}
 | 
						|
 | 
						|
SimpleStack.prototype.popCallback = function()
 | 
						|
{
 | 
						|
	this.implementAction(this.pop.bind(this), "");
 | 
						|
}
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
Finally, we get to the actual meat of our visualization -- the code that does the work.  Note that we are mostly
 | 
						|
just implementing the action, using some calls to cmd to document what we are doing.
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
SimpleStack.prototype.push = function(pushedValue)
 | 
						|
{
 | 
						|
	this.commands = [];
 | 
						|
	
 | 
						|
	this.stackID[this.stackTop] = this.nextIndex++;
 | 
						|
	
 | 
						|
	this.cmd("CreateRectangle", this.stackID[this.stackTop], 
 | 
						|
			                    pushedValue, 
 | 
						|
								SimpleStack.ELEMENT_WIDTH,
 | 
						|
								SimpleStack.ELEMENT_HEIGHT,
 | 
						|
								SimpleStack.INSERT_X, 
 | 
						|
			                    SimpleStack.INSERT_Y);
 | 
						|
	this.cmd("SetForegroundColor", this.stackID[this.stackTop], SimpleStack.FOREGROUND_COLOR);
 | 
						|
	this.cmd("SetBackgroundColor", this.stackID[this.stackTop], SimpleStack.BACKGROUND_COLOR);
 | 
						|
	this.cmd("Step");
 | 
						|
	var nextXPos = SimpleStack.STARTING_X + this.stackTop * SimpleStack.ELEMENT_WIDTH;
 | 
						|
	var nextYPos = SimpleStack.STARTING_Y;
 | 
						|
	this.cmd("Move", this.stackID[this.stackTop], nextXPos, nextYPos);
 | 
						|
	this.cmd("Step"); // Not necessary, but not harmful either
 | 
						|
	this.stackTop++;
 | 
						|
	return this.commands;
 | 
						|
}
 | 
						|
 | 
						|
SimpleStack.prototype.pop = function(unused)
 | 
						|
{
 | 
						|
	this.commands = [];
 | 
						|
	
 | 
						|
	if (this.stackTop > 0)
 | 
						|
	{
 | 
						|
		this.stackTop--;
 | 
						|
		
 | 
						|
		this.cmd("Move", this.stackID[this.stackTop], SimpleStack.INSERT_X, SimpleStack.INSERT_Y);
 | 
						|
		this.cmd("Step");
 | 
						|
		this.cmd("Delete", this.stackID[this.stackTop]);
 | 
						|
		this.cmd("Step");
 | 
						|
		
 | 
						|
		// OPTIONAL:  We can do a little better with memory leaks in our own memory manager by
 | 
						|
		//            reclaiming this memory.  It is recommened that you *NOT* do this unless
 | 
						|
		//            you really know what you are doing (memory management leads to tricky bugs!)
 | 
						|
		//            *and* you really need to (very long runnning visualizaitons, not common)
 | 
						|
		//            Because this is a stack, we can reclaim memory easily.  Most of the time, this
 | 
						|
		//            is not the case, and can be dangerous.
 | 
						|
		// nextIndex = this.stackID[this.stackTop];
 | 
						|
	}
 | 
						|
	return this.commands;
 | 
						|
}
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
Almost done!  Some code to enable / disable our algorithm controls while the animation is running...
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
// Called by our superclass when we get an animation started event -- need to wait for the
 | 
						|
// event to finish before we start doing anything
 | 
						|
SimpleStack.prototype.disableUI = function(event)
 | 
						|
{
 | 
						|
	for (var i = 0; i < this.controls.length; i++)
 | 
						|
	{
 | 
						|
		this.controls[i].disabled = true;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Called by our superclass when we get an animation completed event -- we can
 | 
						|
/// now interact again.
 | 
						|
SimpleStack.prototype.enableUI = function(event)
 | 
						|
{
 | 
						|
	for (var i = 0; i < this.controls.length; i++)
 | 
						|
	{
 | 
						|
		this.controls[i].disabled = false;
 | 
						|
	}
 | 
						|
}
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
Finally, some boilerplate to get everything started.  You can pretty much cut and paste the following
 | 
						|
into your own code, replacing SimpleStack with your function:
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
// Script to start up your function, called from the webapge:
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
var currentAlg;
 | 
						|
 | 
						|
function init()
 | 
						|
{
 | 
						|
	var animManag = initCanvas();
 | 
						|
	currentAlg = new SimpleStack(animManag, canvas.width, canvas.height);
 | 
						|
	
 | 
						|
}
 | 
						|
</div>
 | 
						|
</pre>
 | 
						|
 | 
						|
And we're done.  We just need to create the appriate HTML file to enbed this in, and
 | 
						|
we're good to go.
 | 
						|
 | 
						|
 | 
						|
<h2>HTML Template  </h2>
 | 
						|
This visualization system is a combination of HTML and javascript -- you need a webpage to
 | 
						|
embed the javascript, and that webpage needs the following items:
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> A bunch of <script> tags in the header to load oll of the necessary scripts.  These files need to be
 | 
						|
included in the correct order, based on dependancies. (It would be nice if
 | 
						|
javascript had a standard #include-like mechanism to avoid manually inserting all of these files
 | 
						|
in the HTM.  While there are some ways around
 | 
						|
it -- dynamically inserting the  <script> tags using javascript calls --
 | 
						|
not all browsers seem to work with these somewhat hacky methods.  A brute-force inclusion
 | 
						|
of all the files, in the proper order, works everywhere)</li>
 | 
						|
 | 
						|
<li> An empty table with the id "algoControlSection" where the algorithm specific controls are to be placed</li>
 | 
						|
<li> A canvas element, where the animations will appear</li>
 | 
						|
<li> An empty table with the id "GeneralAnimationControls" where general animation controls are to be placed</li>
 | 
						|
<li> An onload = "init();" command in the body tag to kick everything off </li>
 | 
						|
</ul>
 | 
						|
 | 
						|
The eaiest solition is just to use the following template, changing the values
 | 
						|
that are specific to your application
 | 
						|
 | 
						|
<ul>
 | 
						|
<li> <a href = "template.html">template.html</a>
 | 
						|
</ul>
 | 
						|
 | 
						|
The template file is reproduced below, with the changes you need to make highlighted in <font color = "red">red</font>
 | 
						|
 | 
						|
 | 
						|
<div class = "code">
 | 
						|
<pre>
 | 
						|
<!DOCTYPE html>
 | 
						|
<html>
 | 
						|
    <head>
 | 
						|
        
 | 
						|
        <title>
 | 
						|
           <font color = "red">Place your title here</font>
 | 
						|
        </title>
 | 
						|
        
 | 
						|
        <!-- css sheet for how the page is laid out -->
 | 
						|
        
 | 
						|
        <link rel="stylesheet" href="visualizationPageStyle.css">
 | 
						|
            
 | 
						|
            
 | 
						|
        <!-- jqueury stuff.  Only used for the animation speed slider. -->
 | 
						|
        <link rel="stylesheet" href="ThirdParty/jquery-ui-1.8.11.custom.css">
 | 
						|
                
 | 
						|
        <script src="ThirdParty/jquery-1.5.2.min.js"></script>
 | 
						|
        <script src="ThirdParty/jquery-ui-1.8.11.custom.min.js"></script>
 | 
						|
                
 | 
						|
        <!-- Javascript for the actual visualization code -->
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/CustomEvents.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/UndoFunctions.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/AnimatedObject.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/AnimatedLabel.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/AnimatedCircle.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/AnimatedRectangle.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/AnimatedLinkedList.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/HighlightCircle.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/Line.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/ObjectManager.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AnimationLibrary/AnimationMain.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "AlgorithmLibrary/Algorithm.js"> </script>
 | 
						|
        <script type = "text/javascript" src = "<font color = "red">Place path to your javascript file here</font>"> </script> 
 | 
						|
                
 | 
						|
            
 | 
						|
     </head> 
 | 
						|
    
 | 
						|
    <body onload="init();" class="VisualizationMainPage">
 | 
						|
        
 | 
						|
        <div id = "container">
 | 
						|
            
 | 
						|
            <div id="header">  
 | 
						|
                <h1><font color = "red">Place your Header here</font> </h1>
 | 
						|
            </div>
 | 
						|
            
 | 
						|
            <div = id = "mainContent"> 
 | 
						|
                
 | 
						|
                <div id = "algoControlSection">
 | 
						|
                    <!-- Table for buttons to control specific animation (insert/find/etc) -->
 | 
						|
                    <!-- (filled in by javascript code specific to the animtion) -->
 | 
						|
                    <table id="AlgorithmSpecificControls"> </table> 
 | 
						|
                </div>
 | 
						|
                
 | 
						|
                    <!-- Drawing canvas where all animation is done.  Note:  can be resized in code -->
 | 
						|
                                    
 | 
						|
                <canvas id="canvas" width="1000" height="500"></canvas>
 | 
						|
                
 | 
						|
                <div id = "generalAnimationControlSection">
 | 
						|
                    <!-- Table for buttons to control general animation (play/pause/undo/etc) ->
 | 
						|
                    <!-- (filled in by javascript code, specifically AnimationMain.js)  -->
 | 
						|
 | 
						|
                    <table id="GeneralAnimationControls">  </table>     
 | 
						|
                </div>
 | 
						|
                
 | 
						|
            </div> <!-- mainContent -->
 | 
						|
            
 | 
						|
            <div id="footer">  
 | 
						|
                <p><a href="Algorithms.html">首页</a></p>
 | 
						|
            </div>
 | 
						|
 | 
						|
        </div><!-- container -->
 | 
						|
    </body>
 | 
						|
</html>
 | 
						|
</pre>
 | 
						|
</div>
 | 
						|
 | 
						|
<h2> Quirks and Advanced Techniques </h2>
 | 
						|
 | 
						|
<h3> Object Display Order </h3>
 | 
						|
 | 
						|
If two object overlap, which one is placed on top?  The animation system uses the following rules to determine draw order:
 | 
						|
 | 
						|
<ol>
 | 
						|
<li> All non-highlighted items are drawn <em>before</em> all highlighted items 
 | 
						|
(so highlighted items will appear on top of non-highlighted items)</li> 
 | 
						|
<li> All items with the same highlight state are drawn in order of their identifiers (so objects with larger identifiers
 | 
						|
will be drawn in front of objects with small identifiers)</li>
 | 
						|
</ol> 
 | 
						|
 | 
						|
This system is not terribly sophisticated, but it works well enough.  You just need to be sure that if you want object A 
 | 
						|
to appear in front of object B, then object A has to have a higher object ID.  If a more sophisticated system is required,
 | 
						|
this may be modified in a future release.
 | 
						|
 | 
						|
 | 
						|
<h3> Debugging </h3>
 | 
						|
 | 
						|
Developing in javascript?  <a href = "http://getfirebug.com/">Firebug</a> is a very fine (and very free!) javascript debugger.
 | 
						|
<em>However,</em> there can be a problem with breakpoints.  The animations in this system rely heavily on the javascript
 | 
						|
setTimeout command.  If a timeout is set, and then firebug hits a breakpoint, the timeout will be lost.  Thus, hitting
 | 
						|
a breakpoint in the wrong piece of code (pretty much anything in AnimationMain.js), will cause the animation to 
 | 
						|
stop.  I've managed the use of setTimeout calls so that hitting a breakpoint in code that uses the animation libraries
 | 
						|
(as opposed to code in the libraries themselves) should <em>not</em> cause this problem.
 | 
						|
 | 
						|
</div>
 | 
						|
<div class="footer">Copyright 2011 <a href = "http://www.cs.usfca.edu/galles">David Galles </a> </div>
 | 
						|
 | 
						|
</div>
 | 
						|
 | 
						|
</body>
 | 
						|
</html>
 |