
html_res.adg.jit.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of clover Show documentation
Show all versions of clover Show documentation
Clover is an award winning code coverage and testing tool for Java and Groovy.
It integrates easily with Maven, Ant, Grails, Eclipse and IntelliJ IDEA
as well as with continuous integration servers such as Bamboo, Jenkins or Hudson.
Note: before Clover 4.0 this artifact was named com.cenqua.clover:clover.
The newest version!
(function () {
/*
File: Core.js
Description:
Provides common utility functions and the Class object used internally by the library.
Also provides the object for manipulating JSON tree structures
Some of the Basic utility functions and the Class system are based in the MooTools Framework . Copyright (c) 2006-2009 Valerio Proietti, . MIT license .
Author:
Nicolas Garcia Belmonte
Copyright:
Copyright 2008-2009 by Nicolas Garcia Belmonte.
Homepage:
Version:
1.1.2
License:
BSD License
> Redistribution and use in source and binary forms, with or without
> modification, are permitted provided that the following conditions are met:
> * Redistributions of source code must retain the above copyright
> notice, this list of conditions and the following disclaimer.
> * 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.
> * Neither the name of the organization nor the
> names of its contributors may be used to endorse or promote products
> derived from this software without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY Nicolas Garcia Belmonte ``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 Nicolas Garcia Belmonte 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.
*/
function $empty() {};
function $extend(original, extended){
for (var key in (extended || {})) original[key] = extended[key];
return original;
};
function $lambda(value){
return (typeof value == 'function') ? value : function(){
return value;
};
};
var $time = Date.now || function(){
return +new Date;
};
function $splat(obj){
var type = $type(obj);
return (type) ? ((type != 'array') ? [obj] : obj) : [];
};
var $type = function(elem) {
return $type.s.call(elem).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
};
$type.s = Object.prototype.toString;
function $each(iterable, fn){
var type = $type(iterable);
if(type == 'object') {
for (var key in iterable) fn(iterable[key], key);
} else {
for(var i=0; i < iterable.length; i++) fn(iterable[i], i);
}
};
function $merge(){
var mix = {};
for (var i = 0, l = arguments.length; i < l; i++){
var object = arguments[i];
if ($type(object) != 'object') continue;
for (var key in object){
var op = object[key], mp = mix[key];
mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $merge(mp, op) : $unlink(op);
}
}
return mix;
};
function $unlink(object){
var unlinked;
switch ($type(object)){
case 'object':
unlinked = {};
for (var p in object) unlinked[p] = $unlink(object[p]);
break;
case 'array':
unlinked = [];
for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]);
break;
default: return object;
}
return unlinked;
};
function $rgbToHex(srcArray, array){
if (srcArray.length < 3) return null;
if (srcArray.length == 4 && srcArray[3] == 0 && !array) return 'transparent';
var hex = [];
for (var i = 0; i < 3; i++){
var bit = (srcArray[i] - 0).toString(16);
hex.push((bit.length == 1) ? '0' + bit : bit);
}
return (array) ? hex : '#' + hex.join('');
};
function $destroy(elem) {
$clean(elem);
if(elem.parentNode) elem.parentNode.removeChild(elem);
if(elem.clearAttributes) elem.clearAttributes();
};
function $clean(elem) {
for(var ch = elem.childNodes, i=0; i < ch.length; i++) {
$destroy(ch[i]);
}
};
function $addEvent(obj, type, fn) {
if (obj.addEventListener)
obj.addEventListener(type, fn, false);
else
obj.attachEvent('on' + type, fn);
};
function $hasClass(obj, klass) {
return (' ' + obj.className + ' ').indexOf(' ' + klass + ' ') > -1;
};
function $addClass(obj, klass) {
if(!$hasClass(obj, klass)) obj.className = (obj.className + " " + klass);
};
function $removeClass(obj, klass) {
obj.className = obj.className.replace(new RegExp('(^|\\s)' + klass + '(?:\\s|$)'), '$1');
};
function $get(id) {
return document.getElementById(id);
};
var Class = function(properties){
properties = properties || {};
var klass = function(){
// not defining any attributes in Class properties.
// for (var key in this){
// if (typeof this[key] != 'function') this[key] = $unlink(this[key]);
// }
this.constructor = klass;
if (Class.prototyping) return this;
var instance = (this.initialize) ? this.initialize.apply(this, arguments) : this;
return instance;
};
for (var mutator in Class.Mutators){
if (!properties[mutator]) continue;
properties = Class.Mutators[mutator](properties, properties[mutator]);
delete properties[mutator];
}
$extend(klass, this);
klass.constructor = Class;
klass.prototype = properties;
return klass;
};
Class.Mutators = {
Extends: function(self, klass){
Class.prototyping = klass.prototype;
var subclass = new klass;
delete subclass.parent;
subclass = Class.inherit(subclass, self);
delete Class.prototyping;
return subclass;
},
Implements: function(self, klasses){
$each($splat(klasses), function(klass){
Class.prototying = klass;
$extend(self, ($type(klass) == 'function') ? new klass : klass);
delete Class.prototyping;
});
return self;
}
};
$extend(Class, {
inherit: function(object, properties){
var caller = arguments.callee.caller;
for (var key in properties){
var override = properties[key];
var previous = object[key];
var type = $type(override);
if (previous && type == 'function'){
if (override != previous){
if (caller){
override.__parent = previous;
object[key] = override;
} else {
Class.override(object, key, override);
}
}
} else if(type == 'object'){
object[key] = $merge(previous, override);
} else {
object[key] = override;
}
}
if (caller) object.parent = function(){
return arguments.callee.caller.__parent.apply(this, arguments);
};
return object;
},
override: function(object, name, method){
var parent = Class.prototyping;
if (parent && object[name] != parent[name]) parent = null;
var override = function(){
var previous = this.parent;
this.parent = parent ? parent[name] : object[name];
var value = method.apply(this, arguments);
this.parent = previous;
return value;
};
object[name] = override;
}
});
Class.prototype.implement = function(){
var proto = this.prototype;
$each(Array.prototype.slice.call(arguments || []), function(properties){
Class.inherit(proto, properties);
});
return this;
};
/*
Object: TreeUtil
Some common JSON tree manipulation methods.
*/
this.TreeUtil = {
/*
Method: prune
Clears all tree nodes having depth greater than maxLevel.
Parameters:
tree - A JSON tree object. For more information please see .
maxLevel - An integer specifying the maximum level allowed for this tree. All nodes having depth greater than max level will be deleted.
*/
prune: function(tree, maxLevel) {
this.each(tree, function(elem, i) {
if(i == maxLevel && elem.children) {
delete elem.children;
elem.children = [];
}
});
},
/*
Method: getParent
Returns the parent node of the node having _id_ as id.
Parameters:
tree - A JSON tree object. See also .
id - The _id_ of the child node whose parent will be returned.
Returns:
A tree JSON node if any, or false otherwise.
*/
getParent: function(tree, id) {
if(tree.id == id) return false;
var ch = tree.children;
if(ch && ch.length > 0) {
for(var i=0; i.
id - A node *unique* identifier.
Returns:
A subtree having a root node matching the given id. Returns null if no subtree matching the id is found.
*/
getSubtree: function(tree, id) {
if(tree.id == id) return tree;
for(var i=0, ch=tree.children; i.
maxLevel - _optional_ A subtree's max level.
Returns:
An array having objects with two properties.
- The _node_ property contains the leaf node.
- The _level_ property specifies the depth of the node.
*/
getLeaves: function (node, maxLevel) {
var leaves = [], levelsToShow = maxLevel || Number.MAX_VALUE;
this.each(node, function(elem, i) {
if(i < levelsToShow &&
(!elem.children || elem.children.length == 0 )) {
leaves.push({
'node':elem,
'level':levelsToShow - i
});
}
});
return leaves;
},
/*
Method: eachLevel
Iterates on tree nodes with relative depth less or equal than a specified level.
Parameters:
tree - A JSON tree or subtree. See also .
initLevel - An integer specifying the initial relative level. Usually zero.
toLevel - An integer specifying a top level. This method will iterate only through nodes with depth less than or equal this number.
action - A function that receives a node and an integer specifying the actual level of the node.
Example:
(start code js)
TreeUtil.eachLevel(tree, 0, 3, function(node, depth) {
alert(node.name + ' ' + depth);
});
(end code)
*/
eachLevel: function(tree, initLevel, toLevel, action) {
if(initLevel <= toLevel) {
action(tree, initLevel);
for(var i=0, ch = tree.children; i.
action - A function that receives a node.
Example:
(start code js)
TreeUtil.each(tree, function(node) {
alert(node.name);
});
(end code)
*/
each: function(tree, action) {
this.eachLevel(tree, 0, Number.MAX_VALUE, action);
},
/*
Method: loadSubtrees
Appends subtrees to leaves by requesting new subtrees
with the _request_ method.
Parameters:
tree - A JSON tree node. .
controller - An object that implements a request method.
Example:
(start code js)
TreeUtil.loadSubtrees(leafNode, {
request: function(nodeId, level, onComplete) {
//Pseudo-code to make an ajax request for a new subtree
// that has as root id _nodeId_ and depth _level_ ...
Ajax.request({
'url': 'http://subtreerequesturl/',
onSuccess: function(json) {
onComplete.onComplete(nodeId, json);
}
});
}
});
(end code)
*/
loadSubtrees: function(tree, controller) {
var maxLevel = controller.request && controller.levelsToShow;
var leaves = this.getLeaves(tree, maxLevel),
len = leaves.length,
selectedNode = {};
if(len == 0) controller.onComplete();
for(var i=0, counter=0; i, ,
*/
/*
Class: Canvas
A multi-purpose Canvas Class. This Class can be used with the ExCanvas library to provide
cross browser Canvas based visualizations.
Parameters:
id - The canvas id. This id will be used as prefix for the canvas widget DOM elements ids.
options - An object containing multiple options such as
- _injectInto_ This property is _required_ and it specifies the id of the DOM element
to which the Canvas widget will be appended
- _width_ The width of the Canvas widget. Default's to 200px
- _height_ The height of the Canvas widget. Default's to 200px
- _backgroundColor_ Used for compatibility with IE. The canvas' background color.
Default's to '#333'
- _styles_ A hash containing canvas specific style properties such as _fillStyle_ and _strokeStyle_ among others.
Example:
Suppose we have this HTML
(start code xml)
(end code)
Now we create a new Canvas instance
(start code js)
//Create a new canvas instance
var canvas = new Canvas('mycanvas', {
//Where to inject the canvas. Any div container will do.
'injectInto':'infovis',
//width and height for canvas. Default's to 200.
'width': 900,
'height':500,
//Canvas styles
'styles': {
'fillStyle': '#ccddee',
'strokeStyle': '#772277'
}
});
(end code)
The generated HTML will look like this
(start code xml)
(end code)
As you can see, the generated HTML consists of a canvas DOM element of id _mycanvas-canvas_ and a div label container
of id _mycanvas-label_, wrapped in a main div container of id _mycanvas_.
You can also add a background canvas, for making background drawings.
This is how the background concentric circles are drawn
Example:
(start code js)
//Create a new canvas instance.
var canvas = new Canvas('mycanvas', {
//Where to inject the canvas. Any div container will do.
'injectInto':'infovis',
//width and height for canvas. Default's to 200.
'width': 900,
'height':500,
//Canvas styles
'styles': {
'fillStyle': '#ccddee',
'strokeStyle': '#772277'
},
//Add a background canvas for plotting
//concentric circles.
'backgroundCanvas': {
//Add Canvas styles for the bck canvas.
'styles': {
'fillStyle': '#444',
'strokeStyle': '#444'
},
//Add the initialization and plotting functions.
'impl': {
'init': function() {},
'plot': function(canvas, ctx) {
var times = 6, d = 100;
var pi2 = Math.PI*2;
for(var i=1; i<=times; i++) {
ctx.beginPath();
ctx.arc(0, 0, i * d, 0, pi2, true);
ctx.stroke();
ctx.closePath();
}
}
}
}
});
(end code)
The _backgroundCanvas_ object contains a canvas _styles_ property and
an _impl_ key to be used for implementing background canvas specific code.
The _init_ method is only called once, at the instanciation of the background canvas.
The _plot_ method is called for plotting a Canvas image.
*/
this.Canvas = (function(){
var config = {
'injectInto': 'id',
'width': 200,
'height': 200,
'backgroundColor': '#333333',
'styles': {
'fillStyle': '#000000',
'strokeStyle': '#000000'
},
'backgroundCanvas': false
};
function hasCanvas(){
hasCanvas.t = hasCanvas.t || typeof(HTMLCanvasElement);
return "function" == hasCanvas.t || "object" == hasCanvas.t;
};
function create(tag, prop, styles){
var elem = document.createElement(tag);
(function(obj, prop){
if (prop)
for (var p in prop)
obj[p] = prop[p];
return arguments.callee;
})(elem, prop)(elem.style, styles);
//feature check
if (tag == "canvas" && !hasCanvas() && G_vmlCanvasManager) {
elem = G_vmlCanvasManager.initElement(document.body.appendChild(elem));
}
return elem;
};
function get(id){
return document.getElementById(id);
};
function translateToCenter(canvas, ctx, w, h){
var width = w ? (w - canvas.width) : canvas.width;
var height = h ? (h - canvas.height) : canvas.height;
ctx.translate(width / 2, height / 2);
};
return function(id, opt){
var ctx, bkctx, mainContainer, labelContainer, canvas, bkcanvas;
if (arguments.length < 1)
throw "Arguments missing";
var idLabel = id + "-label", idCanvas = id + "-canvas", idBCanvas = id + "-bkcanvas";
opt = $merge(config, opt ||
{});
//create elements
var dim = {
'width': opt.width,
'height': opt.height
};
mainContainer = create("div", {
'id': id
}, $merge(dim, {
'position': 'relative'
}));
labelContainer = create("div", {
'id': idLabel
}, {
'overflow': 'visible',
'position': 'absolute',
'top': 0,
'left': 0,
'width': dim.width + 'px',
'height': 0
});
var dimPos = {
'position': 'absolute',
'top': 0,
'left': 0,
'width': dim.width + 'px',
'height': dim.height + 'px'
};
canvas = create("canvas", $merge({
'id': idCanvas
}, dim), dimPos);
var bc = opt.backgroundCanvas;
if (bc) {
bkcanvas = create("canvas", $merge({
'id': idBCanvas
}, dim), dimPos);
//append elements
mainContainer.appendChild(bkcanvas);
}
mainContainer.appendChild(canvas);
mainContainer.appendChild(labelContainer);
get(opt.injectInto).appendChild(mainContainer);
//create contexts
ctx = canvas.getContext('2d');
translateToCenter(canvas, ctx);
var st = opt.styles;
for (var s in st)
ctx[s] = st[s];
if (bc) {
bkctx = bkcanvas.getContext('2d');
var st = bc.styles;
for (var s in st)
bkctx[s] = st[s];
translateToCenter(bkcanvas, bkctx);
bc.impl.init(bkcanvas, bkctx);
bc.impl.plot(bkcanvas, bkctx);
}
//create methods
return {
'id': id,
/*
Method: getCtx
Returns the main canvas context object
Returns:
Main canvas context
Example:
(start code js)
var ctx = canvas.getCtx();
//Now I can use the native canvas context
//and for example change some canvas styles
ctx.globalAlpha = 1;
(end code)
*/
getCtx: function(){
return ctx;
},
/*
Method: getElement
Returns the main Canvas DOM wrapper
Returns:
DOM canvas wrapper generated, (i.e the div wrapper element with id _mycanvas_)
Example:
(start code js)
var wrapper = canvas.getElement();
//Returns ... as element
(end code)
*/
getElement: function(){
return mainContainer;
},
/*
Method: resize
Resizes the canvas.
Parameters:
width - New canvas width.
height - New canvas height.
This method can be used with the , or visualizations to resize
the visualizations
Example:
(start code js)
function resizeViz(width, height) {
canvas.resize(width, height);
rgraph.refresh(); //ht.refresh or st.refresh() also work.
rgraph.onAfterCompute();
}
(end code)
*/
resize: function(width, height){
canvas.width = width;
canvas.height = height;
canvas.style.width = width + "px";
canvas.style.height = height + "px";
if (bc) {
bkcanvas.width = width;
bkcanvas.height = height;
bkcanvas.style.width = width + "px";
bkcanvas.style.height = height + "px";
}
translateToCenter(canvas, ctx);
var st = opt.styles;
for (var s in st)
ctx[s] = st[s];
if (bc) {
var st = bc.styles;
for (var s in st)
bkctx[s] = st[s];
translateToCenter(bkcanvas, bkctx);
bc.impl.init(bkcanvas, bkctx);
bc.impl.plot(bkcanvas, bkctx);
}
},
/*
Method: getSize
Returns canvas dimensions.
Returns:
An object with _width_ and _height_ properties.
Example:
(start code js)
canvas.getSize(); //returns { width: 900, height: 500 }
(end code)
*/
getSize: function(){
return {
'width': canvas.width,
'height': canvas.height
};
},
path: function(type, action){
ctx.beginPath();
action(ctx);
ctx[type]();
ctx.closePath();
},
/*
Method: clear
Clears the canvas object.
*/
clear: function(){
var size = this.getSize();
ctx.clearRect(-size.width / 2, -size.height / 2, size.width, size.height);
},
/*
Method: clearReactangle
Same as but only clears a section of the canvas.
Parameters:
top - An integer specifying the top of the rectangle.
right - An integer specifying the right of the rectangle.
bottom - An integer specifying the bottom of the rectangle.
left - An integer specifying the left of the rectangle.
*/
clearRectangle: function(top, right, bottom, left){
//if using excanvas
if (!hasCanvas()) {
var f0 = ctx.fillStyle;
ctx.fillStyle = opt.backgroundColor;
ctx.fillRect(left, top, Math.abs(right - left), Math.abs(bottom - top));
ctx.fillStyle = f0;
}
else {
ctx.clearRect(left, top, Math.abs(right - left), Math.abs(bottom - top));
}
}
};
};
})();
/*
* File: Polar.js
*
* Defines the class.
*
* Description:
*
* The class, just like the class, is used by the , and as a 2D point representation.
*
* See also:
*
*
*
*/
/*
Class: Polar
A multi purpose polar representation.
Description:
The class, just like the class, is used by the , and as a 2D point representation.
See also:
Parameters:
theta - An angle.
rho - The norm.
*/
this.Polar = function(theta, rho) {
this.theta = theta;
this.rho = rho;
};
Polar.prototype = {
/*
Method: getc
Returns a complex number.
Parameters:
simple - _optional_ If *true*, this method will return only an object holding x and y properties and not a instance. Default's *false*.
Returns:
A complex number.
*/
getc: function(simple) {
return this.toComplex(simple);
},
/*
Method: getp
Returns a representation.
Returns:
A variable in polar coordinates.
*/
getp: function() {
return this;
},
/*
Method: set
Sets a number.
Parameters:
v - A or instance.
*/
set: function(v) {
v = v.getp();
this.theta = v.theta; this.rho = v.rho;
},
/*
Method: setc
Sets a number.
Parameters:
x - A number real part.
y - A number imaginary part.
*/
setc: function(x, y) {
this.rho = Math.sqrt(x * x + y * y);
this.theta = Math.atan2(y, x);
if(this.theta < 0) this.theta += Math.PI * 2;
},
/*
Method: setp
Sets a polar number.
Parameters:
theta - A number angle property.
rho - A number rho property.
*/
setp: function(theta, rho) {
this.theta = theta;
this.rho = rho;
},
/*
Method: clone
Returns a copy of the current object.
Returns:
A copy of the real object.
*/
clone: function() {
return new Polar(this.theta, this.rho);
},
/*
Method: toComplex
Translates from polar to cartesian coordinates and returns a new instance.
Parameters:
simple - _optional_ If *true* this method will only return an object with x and y properties (and not the whole instance). Default's *false*.
Returns:
A new instance.
*/
toComplex: function(simple) {
var x = Math.cos(this.theta) * this.rho;
var y = Math.sin(this.theta) * this.rho;
if(simple) return { 'x': x, 'y': y};
return new Complex(x, y);
},
/*
Method: add
Adds two instances.
Parameters:
polar - A number.
Returns:
A new Polar instance.
*/
add: function(polar) {
return new Polar(this.theta + polar.theta, this.rho + polar.rho);
},
/*
Method: scale
Scales a polar norm.
Parameters:
number - A scale factor.
Returns:
A new Polar instance.
*/
scale: function(number) {
return new Polar(this.theta, this.rho * number);
},
/*
Method: equals
Comparison method.
Returns *true* if the theta and rho properties are equal.
Parameters:
c - A number.
Returns:
*true* if the theta and rho parameters for these objects are equal. *false* otherwise.
*/
equals: function(c) {
return this.theta == c.theta && this.rho == c.rho;
},
/*
Method: $add
Adds two instances affecting the current object.
Paramters:
polar - A instance.
Returns:
The changed object.
*/
$add: function(polar) {
this.theta = this.theta + polar.theta; this.rho += polar.rho;
return this;
},
/*
Method: $madd
Adds two instances affecting the current object. The resulting theta angle is modulo 2pi.
Parameters:
polar - A instance.
Returns:
The changed object.
*/
$madd: function(polar) {
this.theta = (this.theta + polar.theta) % (Math.PI * 2); this.rho += polar.rho;
return this;
},
/*
Method: $scale
Scales a polar instance affecting the object.
Parameters:
number - A scaling factor.
Returns:
The changed object.
*/
$scale: function(number) {
this.rho *= number;
return this;
},
/*
Method: interpolate
Calculates a polar interpolation between two points at a given delta moment.
Parameters:
elem - A instance.
delta - A delta factor ranging [0, 1].
Returns:
A new instance representing an interpolation between _this_ and _elem_
*/
interpolate: function(elem, delta) {
var pi = Math.PI, pi2 = pi * 2;
var ch = function(t) {
return (t < 0)? (t % pi2) + pi2 : t % pi2;
};
var tt = this.theta, et = elem.theta;
var sum;
if(Math.abs(tt - et) > pi) {
if(tt > et) {
sum =ch((et + ((tt - pi2) - et) * delta)) ;
} else {
sum =ch((et - pi2 + (tt - (et - pi2)) * delta));
}
} else {
sum =ch((et + (tt - et) * delta)) ;
}
var r = (this.rho - elem.rho) * delta + elem.rho;
return {
'theta': sum,
'rho': r
};
}
};
var $P = function(a, b) { return new Polar(a, b); };
Polar.KER = $P(0, 0);
/*
* File: Complex.js
*
* Defines the class.
*
* Description:
*
* The class, just like the class, is used by the , and as a 2D point representation.
*
* See also:
*
*
*
*/
/*
Class: Complex
A multi-purpose Complex Class with common methods.
Description:
The class, just like the class, is used by the , and as a 2D point representation.
See also:
Parameters:
x - _optional_ A Complex number real part.
y - _optional_ A Complex number imaginary part.
*/
this.Complex = function(x, y) {
this.x = x;
this.y = y;
};
Complex.prototype = {
/*
Method: getc
Returns a complex number.
Returns:
A complex number.
*/
getc: function() {
return this;
},
/*
Method: getp
Returns a representation of this number.
Parameters:
simple - _optional_ If *true*, this method will return only an object holding theta and rho properties and not a instance. Default's *false*.
Returns:
A variable in coordinates.
*/
getp: function(simple) {
return this.toPolar(simple);
},
/*
Method: set
Sets a number.
Parameters:
c - A or instance.
*/
set: function(c) {
c = c.getc(true);
this.x = c.x;
this.y = c.y;
},
/*
Method: setc
Sets a complex number.
Parameters:
x - A number Real part.
y - A number Imaginary part.
*/
setc: function(x, y) {
this.x = x;
this.y = y;
},
/*
Method: setp
Sets a polar number.
Parameters:
theta - A number theta property.
rho - A number rho property.
*/
setp: function(theta, rho) {
this.x = Math.cos(theta) * rho
this.y = Math.sin(theta) * rho;
},
/*
Method: clone
Returns a copy of the current object.
Returns:
A copy of the real object.
*/
clone: function() {
return new Complex(this.x, this.y);
},
/*
Method: toPolar
Transforms cartesian to polar coordinates.
Parameters:
simple - _optional_ If *true* this method will only return an object with theta and rho properties (and not the whole instance). Default's *false*.
Returns:
A new instance.
*/
toPolar: function(simple) {
var rho = this.norm();
var atan = Math.atan2(this.y, this.x);
if(atan < 0) atan += Math.PI * 2;
if(simple) return { 'theta': atan, 'rho': rho };
return new Polar(atan, rho);
},
/*
Method: norm
Calculates a number norm.
Returns:
A real number representing the complex norm.
*/
norm: function () {
return Math.sqrt(this.squaredNorm());
},
/*
Method: squaredNorm
Calculates a number squared norm.
Returns:
A real number representing the complex squared norm.
*/
squaredNorm: function () {
return this.x*this.x + this.y*this.y;
},
/*
Method: add
Returns the result of adding two complex numbers.
Does not alter the original object.
Parameters:
pos - A instance.
Returns:
The result of adding two complex numbers.
*/
add: function(pos) {
return new Complex(this.x + pos.x, this.y + pos.y);
},
/*
Method: prod
Returns the result of multiplying two numbers.
Does not alter the original object.
Parameters:
pos - A instance.
Returns:
The result of multiplying two complex numbers.
*/
prod: function(pos) {
return new Complex(this.x*pos.x - this.y*pos.y, this.y*pos.x + this.x*pos.y);
},
/*
Method: conjugate
Returns the conjugate of this number.
Does not alter the original object.
Returns:
The conjugate of this number.
*/
conjugate: function() {
return new Complex(this.x, -this.y);
},
/*
Method: scale
Returns the result of scaling a instance.
Does not alter the original object.
Parameters:
factor - A scale factor.
Returns:
The result of scaling this complex to a factor.
*/
scale: function(factor) {
return new Complex(this.x * factor, this.y * factor);
},
/*
Method: equals
Comparison method.
Returns *true* if both real and imaginary parts are equal.
Parameters:
c - A instance.
Returns:
A boolean instance indicating if both numbers are equal.
*/
equals: function(c) {
return this.x == c.x && this.y == c.y;
},
/*
Method: $add
Returns the result of adding two numbers.
Alters the original object.
Parameters:
pos - A instance.
Returns:
The result of adding two complex numbers.
*/
$add: function(pos) {
this.x += pos.x; this.y += pos.y;
return this;
},
/*
Method: $prod
Returns the result of multiplying two numbers.
Alters the original object.
Parameters:
pos - A instance.
Returns:
The result of multiplying two complex numbers.
*/
$prod:function(pos) {
var x = this.x, y = this.y
this.x = x*pos.x - y*pos.y;
this.y = y*pos.x + x*pos.y;
return this;
},
/*
Method: $conjugate
Returns the conjugate for this .
Alters the original object.
Returns:
The conjugate for this complex.
*/
$conjugate: function() {
this.y = -this.y;
return this;
},
/*
Method: $scale
Returns the result of scaling a instance.
Alters the original object.
Parameters:
factor - A scale factor.
Returns:
The result of scaling this complex to a factor.
*/
$scale: function(factor) {
this.x *= factor; this.y *= factor;
return this;
},
/*
Method: $div
Returns the division of two numbers.
Alters the original object.
Parameters:
pos - A number.
Returns:
The result of scaling this complex to a factor.
*/
$div: function(pos) {
var x = this.x, y = this.y;
var sq = pos.squaredNorm();
this.x = x * pos.x + y * pos.y; this.y = y * pos.x - x * pos.y;
return this.$scale(1 / sq);
}
};
var $C = function(a, b) { return new Complex(a, b); };
Complex.KER = $C(0, 0);
/*
* File: Graph.js
*
* Generic , and classes.
*
* Used by:
*
* , and .
*
*/
/*
Class: Graph
A generic Graph class.
Description:
When a json graph/tree structure is loaded by , an internal representation is created.
In most cases you'll be dealing with an already created structure, so methods like or won't
be of many use. However methods like and are pretty useful.
provides also iterators for and advanced and useful graph operations and methods.
Used by:
, , and .
Access:
An instance of this class can be accessed by using the _graph_ parameter of a , or instance
Example:
(start code js)
var st = new ST(canvas, config);
st.graph.getNode //or any other method.
var ht = new Hypertree(canvas, config);
ht.graph.getNode //or any other method.
var rg = new RGraph(canvas, config);
rg.graph.getNode //or any other method.
(end code)
*/
this.Graph = new Class({
initialize: function(opt) {
var innerOptions = {
'complex': false,
'Node': {}
};
this.opt = $merge(innerOptions, opt || {});
this.nodes= {};
},
/*
Method: getNode
Returns a by _id_.
Parameters:
id - A id.
Returns:
A having _id_ as id. Returns *false* otherwise.
Example:
(start code js)
var node = graph.getNode('someid');
(end code)
*/
getNode: function(id) {
if(this.hasNode(id)) return this.nodes[id];
return false;
},
/*
Method: getAdjacence
Returns an array of objects connecting nodes with ids _id_ and _id2_.
Parameters:
id - A id.
id2 - A id.
Returns:
An Array of objects. Returns *false* if there's not a connecting those two nodes.
*/
getAdjacence: function (id, id2) {
var adjs = [];
if(this.hasNode(id) && this.hasNode(id2)
&& this.nodes[id].adjacentTo({ 'id':id2 }) && this.nodes[id2].adjacentTo({ 'id':id })) {
adjs.push(this.nodes[id].getAdjacency(id2));
adjs.push(this.nodes[id2].getAdjacency(id));
return adjs;
}
return false;
},
/*
Method: addNode
Adds a node.
Parameters:
obj - An object containing as properties
- _id_ node's id
- _name_ node's name
- _data_ node's data hash
See also:
*/
addNode: function(obj) {
if(!this.nodes[obj.id]) {
this.nodes[obj.id] = new Graph.Node($extend({
'id': obj.id,
'name': obj.name,
'data': obj.data
}, this.opt.Node), this.opt.complex);
}
return this.nodes[obj.id];
},
/*
Method: addAdjacence
Connects nodes specified by _obj_ and _obj2_. If not found, nodes are created.
Parameters:
obj - a object.
obj2 - Another object.
data - A DataSet object. Used to store some extra information in the object created.
See also:
,
*/
addAdjacence: function (obj, obj2, data) {
var adjs = []
if(!this.hasNode(obj.id)) this.addNode(obj);
if(!this.hasNode(obj2.id)) this.addNode(obj2);
obj = this.nodes[obj.id]; obj2 = this.nodes[obj2.id];
for(var i in this.nodes) {
if(this.nodes[i].id == obj.id) {
if(!this.nodes[i].adjacentTo(obj2)) {
adjs.push(this.nodes[i].addAdjacency(obj2, data));
}
}
if(this.nodes[i].id == obj2.id) {
if(!this.nodes[i].adjacentTo(obj)) {
adjs.push(this.nodes[i].addAdjacency(obj, data));
}
}
}
return adjs;
},
/*
Method: removeNode
Removes a matching the specified _id_.
Parameters:
id - A node's id.
*/
removeNode: function(id) {
if(this.hasNode(id)) {
var node = this.nodes[id];
for(var i=0 in node.adjacencies) {
var adj = node.adjacencies[i];
this.removeAdjacence(id, adj.nodeTo.id);
}
delete this.nodes[id];
}
},
/*
Method: removeAdjacence
Removes a matching _id1_ and _id2_.
Parameters:
id1 - A id.
id2 - A id.
*/
removeAdjacence: function(id1, id2) {
if(this.hasNode(id1)) this.nodes[id1].removeAdjacency(id2);
if(this.hasNode(id2)) this.nodes[id2].removeAdjacency(id1);
},
/*
Method: hasNode
Returns a Boolean instance indicating if the node belongs to the or not.
Parameters:
id - Node id.
Returns:
A Boolean instance indicating if the node belongs to the graph or not.
*/
hasNode: function(id) {
return id in this.nodes;
}
});
/*
Class: Graph.Node
A node.
Parameters:
obj - An object containing an 'id', 'name' and 'data' properties as described in .
complex - Whether node position properties should contain or instances.
See also:
Description:
An instance of is usually passed as parameter for most configuration/controller methods in the
, and classes.
A object has as properties
id - Node id.
name - Node name.
data - Node data property containing a hash (i.e {}) with custom options. For more information see .
selected - Whether the node is selected or not. Used by for selecting nodes that are between the root node and the selected node.
angleSpan - For radial layouts such as the ones performed by the and the . Contains _begin_ and _end_ properties containing angle values describing the angle span for this subtree.
alpha - Current opacity value.
startAlpha - Opacity begin value. Used for interpolation.
endAlpha - Opacity end value. Used for interpolation.
pos - Current position. Can be a or instance.
startPos - Starting position. Used for interpolation.
endPos - Ending position. Used for interpolation.
*/
Graph.Node = new Class({
initialize: function(opt, complex) {
var innerOptions = {
'id': '',
'name': '',
'data': {},
'adjacencies': {},
'selected': false,
'drawn': false,
'exist': false,
'angleSpan': {
'begin': 0,
'end' : 0
},
'alpha': 1,
'startAlpha': 1,
'endAlpha': 1,
'pos': (complex && $C(0, 0)) || $P(0, 0),
'startPos': (complex && $C(0, 0)) || $P(0, 0),
'endPos': (complex && $C(0, 0)) || $P(0, 0)
};
$extend(this, $extend(innerOptions, opt));
},
/*
Method: adjacentTo
Indicates if the node is adjacent to the node specified by id
Parameters:
id - A node id.
Returns:
A Boolean instance indicating whether this node is adjacent to the specified by id or not.
Example:
(start code js)
node.adjacentTo('mynodeid');
(end code)
*/
adjacentTo: function(node) {
return node.id in this.adjacencies;
},
/*
Method: getAdjacency
Returns a object connecting the current and the node having _id_ as id.
Parameters:
id - A node id.
Returns:
A object or undefined.
*/
getAdjacency: function(id) {
return this.adjacencies[id];
},
/*
Method: addAdjacency
Connects the current node and the given node.
Parameters:
node - A .
data - Some custom hash information.
*/
addAdjacency: function(node, data) {
var adj = new Graph.Adjacence(this, node, data);
return this.adjacencies[node.id] = adj;
},
/*
Method: removeAdjacency
Removes a by _id_.
Parameters:
id - A node id.
*/
removeAdjacency: function(id) {
delete this.adjacencies[id];
}
});
/*
Class: Graph.Adjacence
A adjacence (or edge). Connects two .
Parameters:
nodeFrom - A .
nodeTo - A .
data - Some custom hash data.
See also:
Description:
An instance of is usually passed as parameter for some configuration/controller methods in the
, and classes.
A object has as properties
nodeFrom - A connected by this edge.
nodeTo - Another connected by this edge.
data - Node data property containing a hash (i.e {}) with custom options. For more information see .
alpha - Current opacity value.
startAlpha - Opacity begin value. Used for interpolation.
endAlpha - Opacity end value. Used for interpolation.
*/
Graph.Adjacence = function(nodeFrom, nodeTo, data) {
this.nodeFrom = nodeFrom;
this.nodeTo = nodeTo;
this.data = data || {};
this.alpha = 1;
this.startAlpha = 1;
this.endAlpha = 1;
};
/*
Object: Graph.Util
traversal and processing utility object.
*/
Graph.Util = {
/*
filter
For internal use only. Provides a filtering function based on flags.
*/
filter: function(param) {
if(!param || !($type(param) == 'string')) return function() { return true; };
var props = param.split(" ");
return function(elem) {
for(var i=0; i by _id_.
Parameters:
graph - A instance.
id - A id.
Returns:
A node.
Example:
(start code js)
Graph.Util.getNode(graph, 'nodeid');
(end code)
*/
getNode: function(graph, id) {
return graph.getNode(id);
},
/*
Method: eachNode
Iterates over nodes performing an _action_.
Parameters:
graph - A instance.
action - A callback function having a as first formal parameter.
Example:
(start code js)
Graph.Util.each(graph, function(node) {
alert(node.name);
});
(end code)
*/
eachNode: function(graph, action, flags) {
var filter = this.filter(flags);
for(var i in graph.nodes) if(filter(graph.nodes[i])) action(graph.nodes[i]);
},
/*
Method: eachAdjacency
Iterates over adjacencies applying the _action_ function.
Parameters:
node - A .
action - A callback function having as first formal parameter.
Example:
(start code js)
Graph.Util.eachAdjacency(node, function(adj) {
alert(adj.nodeTo.name);
});
(end code)
*/
eachAdjacency: function(node, action, flags) {
var adj = node.adjacencies, filter = this.filter(flags);
for(var id in adj) if(filter(adj[id])) action(adj[id], id);
},
/*
Method: computeLevels
Performs a BFS traversal setting the correct depth for each node.
The depth of each node can then be accessed by
>node._depth
Parameters:
graph - A .
id - A starting node id for the BFS traversal.
startDepth - _optional_ A minimum depth value. Default's 0.
*/
computeLevels: function(graph, id, startDepth, flags) {
startDepth = startDepth || 0;
var filter = this.filter(flags);
this.eachNode(graph, function(elem) {
elem._flag = false;
elem._depth = -1;
}, flags);
var root = graph.getNode(id);
root._depth = startDepth;
var queue = [root];
while(queue.length != 0) {
var node = queue.pop();
node._flag = true;
this.eachAdjacency(node, function(adj) {
var n = adj.nodeTo;
if(n._flag == false && filter(n)) {
if(n._depth < 0) n._depth = node._depth + 1 + startDepth;
queue.unshift(n);
}
}, flags);
}
},
/*
Method: eachBFS
Performs a BFS traversal applying _action_ to each .
Parameters:
graph - A .
id - A starting node id for the BFS traversal.
action - A callback function having a as first formal parameter.
Example:
(start code js)
Graph.Util.eachBFS(graph, 'mynodeid', function(node) {
alert(node.name);
});
(end code)
*/
eachBFS: function(graph, id, action, flags) {
var filter = this.filter(flags);
this.clean(graph);
var queue = [graph.getNode(id)];
while(queue.length != 0) {
var node = queue.pop();
node._flag = true;
action(node, node._depth);
this.eachAdjacency(node, function(adj) {
var n = adj.nodeTo;
if(n._flag == false && filter(n)) {
n._flag = true;
queue.unshift(n);
}
}, flags);
}
},
/*
Method: eachLevel
Iterates over a node's subgraph applying _action_ to the nodes of relative depth between _levelBegin_ and _levelEnd_.
Parameters:
node - A .
levelBegin - A relative level value.
levelEnd - A relative level value.
action - A callback function having a as first formal parameter.
*/
eachLevel: function(node, levelBegin, levelEnd, action, flags) {
var d = node._depth, filter = this.filter(flags), that = this;
levelEnd = levelEnd === false? Number.MAX_VALUE -d : levelEnd;
(function loopLevel(node, levelBegin, levelEnd) {
var d = node._depth;
if(d >= levelBegin && d <= levelEnd && filter(node)) action(node, d);
if(d < levelEnd) {
that.eachAdjacency(node, function(adj) {
var n = adj.nodeTo;
if(n._depth > d) loopLevel(n, levelBegin, levelEnd);
});
}
})(node, levelBegin + d, levelEnd + d);
},
/*
Method: eachSubgraph
Iterates over a node's children recursively.
Parameters:
node - A .
action - A callback function having a as first formal parameter.
Example:
(start code js)
Graph.Util.eachSubgraph(node, function(node) {
alert(node.name);
});
(end code)
*/
eachSubgraph: function(node, action, flags) {
this.eachLevel(node, 0, false, action, flags);
},
/*
Method: eachSubnode
Iterates over a node's children (without deeper recursion).
Parameters:
node - A .
action - A callback function having a as first formal parameter.
Example:
(start code js)
Graph.Util.eachSubnode(node, function(node) {
alert(node.name);
});
(end code)
*/
eachSubnode: function(node, action, flags) {
this.eachLevel(node, 1, 1, action, flags);
},
/*
Method: anySubnode
Returns *true* if any subnode matches the given condition.
Parameters:
node - A .
cond - A callback function returning a Boolean instance. This function has as first formal parameter a .
Returns:
A boolean value.
Example:
(start code js)
Graph.Util.anySubnode(node, function(node) { return node.name == "mynodename"; });
(end code)
*/
anySubnode: function(node, cond, flags) {
var flag = false;
cond = cond || $lambda(true);
var c = $type(cond) == 'string'? function(n) { return n[cond]; } : cond;
this.eachSubnode(node, function(elem) {
if(c(elem)) flag = true;
}, flags);
return flag;
},
/*
Method: getSubnodes
Collects all subnodes for a specified node. The _level_ parameter filters nodes having relative depth of _level_ from the root node.
Parameters:
node - A .
level - _optional_ A starting relative depth for collecting nodes. Default's 0.
Returns:
An array of nodes.
*/
getSubnodes: function(node, level, flags) {
var ans = [], that = this;
level = level || 0;
if($type(level) == 'array') {
var levelStart = level[0];
var levelEnd = level[1];
} else {
var levelStart = level;
var levelEnd = Number.MAX_VALUE - node._depth;
}
this.eachLevel(node, levelStart, levelEnd, function(n) {
ans.push(n);
}, flags);
return ans;
},
/*
Method: getParents
Returns an Array of wich are parents of the given node.
Parameters:
node - A .
Returns:
An Array of .
Example:
(start code js)
var pars = Graph.Util.getParents(node);
if(pars.length > 0) {
//do stuff with parents
}
(end code)
*/
getParents: function(node) {
var ans = [];
this.eachAdjacency(node, function(adj) {
var n = adj.nodeTo;
if(n._depth < node._depth) ans.push(n);
});
return ans;
},
/*
Method: clean
Cleans flags from nodes (by setting the _flag_ property to false).
Parameters:
graph - A instance.
*/
clean: function(graph) { this.eachNode(graph, function(elem) { elem._flag = false; }); }
};
/*
* File: Graph.Op.js
*
* Defines an abstract class for performing Operations.
*/
/*
Object: Graph.Op
Generic Operations.
Description:
An abstract class holding unary and binary powerful graph operations such as removingNodes, removingEdges, adding two graphs and morphing.
Implemented by:
, and .
Access:
The subclasses for this abstract class can be accessed by using the _op_ property of the , or instances created.
See also:
, , , , , , .
*/
Graph.Op = {
options: {
type: 'nothing',
duration: 2000,
hideLabels: true,
fps:30
},
/*
Method: removeNode
Removes one or more from the visualization.
It can also perform several animations like fading sequentially, fading concurrently, iterating or replotting.
Parameters:
node - The node's id. Can also be an array having many ids.
opt - Animation options. It's an object with optional properties
- _type_ Type of the animation. Can be "nothing", "replot", "fade:seq", "fade:con" or "iter". Default's "nothing".
- _duration_ Duration of the animation in milliseconds. Default's 2000.
- _fps_ Frames per second for the animation. Default's 30.
- _hideLabels_ Hide labels during the animation. Default's *true*.
- _transition_ Transitions defined in the class. Default's the default transition option of the
, or instance created.
Example:
(start code js)
var rg = new RGraph(canvas, config); //could be new ST or new Hypertree also.
rg.op.removeNode('nodeid', {
type: 'fade:seq',
duration: 1000,
hideLabels: false,
transition: Trans.Quart.easeOut
});
//or also
rg.op.removeNode(['someid', 'otherid'], {
type: 'fade:con',
duration: 1500
});
(end code)
*/
removeNode: function(node, opt) {
var viz = this.viz;
var options = $merge(this.options, viz.controller, opt);
var n = $splat(node);
switch(options.type) {
case 'nothing':
for(var i=0; i class. Default's the default transition option of the
, or instance created.
Example:
(start code js)
var rg = new RGraph(canvas, config); //could be new ST or new Hypertree also.
rg.op.removeEdge(['nodeid', 'otherid'], {
type: 'fade:seq',
duration: 1000,
hideLabels: false,
transition: Trans.Quart.easeOut
});
//or also
rg.op.removeEdge([['someid', 'otherid'], ['id3', 'id4']], {
type: 'fade:con',
duration: 1500
});
(end code)
*/
removeEdge: function(vertex, opt) {
var viz = this.viz;
var options = $merge(this.options, viz.controller, opt);
var v = ($type(vertex[0]) == 'string')? [vertex] : vertex;
switch(options.type) {
case 'nothing':
for(var i=0; i
Parameters:
json - A json tree or graph structure. See also .
opt - Animation options. It's an object with optional properties
- _type_ Type of the animation. Can be "nothing", "replot", "fade:seq" or "fade:con". Default's "nothing".
- _duration_ Duration of the animation in milliseconds. Default's 2000.
- _fps_ Frames per second for the animation. Default's 30.
- _hideLabels_ Hide labels during the animation. Default's *true*.
- _transition_ Transitions defined in the class. Default's the default transition option of the
, or instance created.
Example:
(start code js)
//json contains a tree or graph structure.
var rg = new RGraph(canvas, config); //could be new ST or new Hypertree also.
rg.op.sum(json, {
type: 'fade:seq',
duration: 1000,
hideLabels: false,
transition: Trans.Quart.easeOut
});
//or also
rg.op.sum(json, {
type: 'fade:con',
duration: 1500
});
(end code)
*/
sum: function(json, opt) {
var viz = this.viz;
var options = $merge(this.options, viz.controller, opt), root = viz.root;
viz.root = opt.id || viz.root;
switch(options.type) {
case 'nothing':
var graph = viz.construct(json), GUtil = Graph.Util;
GUtil.eachNode(graph, function(elem) {
GUtil.eachAdjacency(elem, function(adj) {
viz.graph.addAdjacence(adj.nodeFrom, adj.nodeTo, adj.data);
});
});
break;
case 'replot':
viz.refresh(true);
this.sum(json, { type: 'nothing' });
viz.refresh(true);
break;
case 'fade:seq': case 'fade': case 'fade:con':
var GUtil = Graph.Util, that = this, graph = viz.construct(json);
//set alpha to 0 for nodes to add.
var fadeEdges = this.preprocessSum(graph);
var modes = !fadeEdges? ['fade:nodes'] : ['fade:nodes', 'fade:vertex'];
viz.reposition();
if(options.type != 'fade:con') {
viz.fx.animate($merge(options, {
modes: ['linear'],
onComplete: function() {
viz.fx.animate($merge(options, {
modes: modes,
onComplete: function() {
options.onComplete();
}
}));
}
}));
} else {
GUtil.eachNode(viz.graph, function(elem) {
if (elem.id != root && elem.pos.getp().equals(Polar.KER)) {
elem.pos.set(elem.endPos); elem.startPos.set(elem.endPos);
}
});
viz.fx.animate($merge(options, {
modes: ['linear'].concat(modes)
}));
}
break;
default: this.doError();
}
},
/*
Method: morph
This method will _morph_ the current visualized graph into the new _json_ representation passed in the method.
Can also perform multiple animations. The _json_ object must at least have the root node in common with the current visualized graph.
Parameters:
json - A json tree or graph structure. See also .
opt - Animation options. It's an object with optional properties
- _type_ Type of the animation. Can be "nothing", "replot", or "fade". Default's "nothing".
- _duration_ Duration of the animation in milliseconds. Default's 2000.
- _fps_ Frames per second for the animation. Default's 30.
- _hideLabels_ Hide labels during the animation. Default's *true*.
- _transition_ Transitions defined in the class. Default's the default transition option of the
, or instance created.
Example:
(start code js)
//json contains a tree or graph structure.
var rg = new RGraph(canvas, config); //could be new ST or new Hypertree also.
rg.op.morph(json, {
type: 'fade',
duration: 1000,
hideLabels: false,
transition: Trans.Quart.easeOut
});
//or also
rg.op.morph(json, {
type: 'fade',
duration: 1500
});
(end code)
*/
morph: function(json, opt) {
var viz = this.viz;
var options = $merge(this.options, viz.controller, opt), root = viz.root;
viz.root = opt.id || viz.root;
switch(options.type) {
case 'nothing':
var graph = viz.construct(json), GUtil = Graph.Util;
GUtil.eachNode(graph, function(elem) {
GUtil.eachAdjacency(elem, function(adj) {
viz.graph.addAdjacence(adj.nodeFrom, adj.nodeTo, adj.data);
});
});
GUtil.eachNode(viz.graph, function(elem) {
GUtil.eachAdjacency(elem, function(adj) {
if(!graph.getAdjacence(adj.nodeFrom.id, adj.nodeTo.id)) {
viz.graph.removeAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
}
});
if(!graph.hasNode(elem.id)) viz.graph.removeNode(elem.id);
});
break;
case 'replot':
viz.refresh(true);
this.morph(json, { type: 'nothing' });
viz.fx.clearLabels();
viz.refresh(true);
break;
case 'fade:seq': case 'fade': case 'fade:con':
var GUtil = Graph.Util, that = this, graph = viz.construct(json);
//preprocessing for adding nodes.
var fadeEdges = this.preprocessSum(graph);
//preprocessing for nodes to delete.
GUtil.eachNode(viz.graph, function(elem) {
if(!graph.hasNode(elem.id)) {
elem.alpha = 1; elem.startAlpha = 1; elem.endAlpha = 0; elem.ignore = true;
}
});
GUtil.eachNode(viz.graph, function(elem) {
if(elem.ignore) return;
GUtil.eachAdjacency(elem, function(adj) {
if(adj.nodeFrom.ignore || adj.nodeTo.ignore) return;
var nodeFrom = graph.getNode(adj.nodeFrom.id);
var nodeTo = graph.getNode(adj.nodeTo.id);
if(!nodeFrom.adjacentTo(nodeTo)) {
var adjs = viz.graph.getAdjacence(nodeFrom.id, nodeTo.id);
fadeEdges = true;
adjs[0].alpha = 1; adjs[0].startAlpha = 1; adjs[0].endAlpha = 0; adjs[0].ignore = true;
adjs[1].alpha = 1; adjs[1].startAlpha = 1; adjs[1].endAlpha = 0; adjs[1].ignore = true;
}
});
});
var modes = !fadeEdges? ['fade:nodes'] : ['fade:nodes', 'fade:vertex'];
viz.reposition();
GUtil.eachNode(viz.graph, function(elem) {
if (elem.id != root && elem.pos.getp().equals(Polar.KER)) {
elem.pos.set(elem.endPos); elem.startPos.set(elem.endPos);
}
});
viz.fx.animate($merge(options, {
modes: ['polar'].concat(modes),
onComplete: function() {
GUtil.eachNode(viz.graph, function(elem) {
if(elem.ignore) viz.graph.removeNode(elem.id);
});
GUtil.eachNode(viz.graph, function(elem) {
GUtil.eachAdjacency(elem, function(adj) {
if(adj.ignore) viz.graph.removeAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
});
});
options.onComplete();
}
}));
break;
default: this.doError();
}
},
preprocessSum: function(graph) {
var viz = this.viz;
var GUtil = Graph.Util;
GUtil.eachNode(graph, function(elem) {
if(!viz.graph.hasNode(elem.id)) {
viz.graph.addNode(elem);
var n = viz.graph.getNode(elem.id);
n.alpha = 0; n.startAlpha = 0; n.endAlpha = 1;
}
});
var fadeEdges = false;
GUtil.eachNode(graph, function(elem) {
GUtil.eachAdjacency(elem, function(adj) {
var nodeFrom = viz.graph.getNode(adj.nodeFrom.id);
var nodeTo = viz.graph.getNode(adj.nodeTo.id);
if(!nodeFrom.adjacentTo(nodeTo)) {
var adjs = viz.graph.addAdjacence(nodeFrom, nodeTo, adj.data);
if(nodeFrom.startAlpha == nodeFrom.endAlpha
&& nodeTo.startAlpha == nodeTo.endAlpha) {
fadeEdges = true;
adjs[0].alpha = 0; adjs[0].startAlpha = 0; adjs[0].endAlpha = 1;
adjs[1].alpha = 0; adjs[1].startAlpha = 0; adjs[1].endAlpha = 1;
}
}
});
});
return fadeEdges;
}
};
/*
* File: Graph.Plot.js
*
* Defines an abstract class for performing rendering and animation.
*
*/
/*
Object: Graph.Plot
Generic rendering and animation methods.
Description:
An abstract class for plotting a generic graph structure.
Implemented by:
, , .
Access:
The subclasses for this abstract class can be accessed by using the _fx_ property of the , , or instances created.
See also:
, , , , , ,