Author: clopes
Date: 2011-10-12 14:53:07 -0700 (Wed, 12 Oct 2011)
New Revision: 27146
Modified:
cytoscapeweb/branches/compound/html-template/js/compound.js
cytoscapeweb/branches/compound/html-template/js/cytoscapeweb.js
cytoscapeweb/branches/compound/html-template/sample.html
cytoscapeweb/branches/compound/src/org/cytoscapeweb/model/GraphProxy.as
cytoscapeweb/branches/compound/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
cytoscapeweb/branches/compound/src/org/cytoscapeweb/util/CompoundNodes.as
cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/ExternalMediator.as
cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/GraphMediator.as
cytoscapeweb/branches/compound/src/org/cytoscapeweb/vis/data/CompoundNodeSprite.as
Log:
Added verification for circular references between child and parent nodes when
adding new elements.
JS API: Removed parentId parameter from addNode()--using data.parent instead.
Auto initializing compound node when adding a child, if it is not already
initialized.
GraphMediator no longer initializes a compound node when updating it, in order
to prevent event listeners from being added twice (a compound node is
initialized as a regular node before being updated as compound anyway).
Modified: cytoscapeweb/branches/compound/html-template/js/compound.js
===================================================================
--- cytoscapeweb/branches/compound/html-template/js/compound.js 2011-10-12
21:17:32 UTC (rev 27145)
+++ cytoscapeweb/branches/compound/html-template/js/compound.js 2011-10-12
21:53:07 UTC (rev 27146)
@@ -55,8 +55,8 @@
nodes: {
// regular nodes
size: 40,
- color: "#8a1b0b",
- image: "http://www.cs.bilkent.edu.tr/~ssumer/cw/cw-logo.png",
+ color: "#dafbab",
+ //image: "http://www.cs.bilkent.edu.tr/~ssumer/cw/cw-logo.png",
// compound nodes
/*
compoundPaddingLeft: 20,
@@ -68,7 +68,7 @@
compoundLabelFontSize: 15,
compoundLabelVerticalAnchor: "bottom"
*/
- compoundImage:
"http://www.cs.bilkent.edu.tr/~ivis/images/ivis-logo.png",
+ //compoundImage:
"http://www.cs.bilkent.edu.tr/~ivis/images/ivis-logo.png",
compoundPaddingLeft: 10,
compoundPaddingRight: 10,
compoundPaddingTop: 10,
Modified: cytoscapeweb/branches/compound/html-template/js/cytoscapeweb.js
===================================================================
--- cytoscapeweb/branches/compound/html-template/js/cytoscapeweb.js
2011-10-12 21:17:32 UTC (rev 27145)
+++ cytoscapeweb/branches/compound/html-template/js/cytoscapeweb.js
2011-10-12 21:53:07 UTC (rev 27146)
@@ -704,6 +704,7 @@
/**
* <p>Create a new node and add it to the network view.<p>
+ * <p>You can also add a node as a child of another node, by setting
the parent node ID to the "parent" data attribute.<p>
* <p>If the node <code>id</code> is not specified, Cytoscape Web
creates a new one automatically.</p>
* <p>If the data contains attributes that have not been previously
defined in the {@link org.cytoscapeweb.DataSchema},
* Cytoscape Web will throw an error. To prevent that, you simply add
the new fields to the schema first,
@@ -711,16 +712,19 @@
* <p>Keep in mind that {@link
org.cytoscapeweb.Visualization#addElements} is much faster if you have to
* add more than one element at once.</p>
* @example
+ * // 1. Add a new node to the network (here we assume that the data
fields for
+ * // "label" and "weight" already exists in the node schema):
* var data = { id: "n4",
* label: "MYO2 (Yeast)",
* weight: 0.54 };
+ * var node1 = vis.addNode(240, 360, data, true);
*
- * var node = vis.addNode(240, 360, data, true);
- *
+ * // 2. Add a new node as a child of another (compound) node:
+ * var node2 = vis.addNode(node1.x, node1.y, { parent: "n4" }, true);
+ *
* @param {Object} x The horizontal coordinate of the node.
* @param {Object} y The vertical coordinate of the node.
* @param {Object} [data] The object that contains the node attributes.
- * @param {Object} [parentId] Optional parent node's ID.
* @param {Boolean} [updateVisualMappers] It tells Cytoscape Web to
update and reapply the visual mappers
* to the network view after
adding the node.
* The default value is
<code>false</code>.
@@ -729,7 +733,7 @@
* @see org.cytoscapeweb.Visualization#addElements
* @see org.cytoscapeweb.Visualization#removeElements
*/
- addNode: function (x, y/*, data, parentId, updateVisualMappers*/) {
+ addNode: function (x, y/*, data, updateVisualMappers*/) {
var data;
var updateVisualMappers = false;
var parentId = null;
@@ -737,12 +741,10 @@
if (arguments.length > i && (typeof arguments[i] === "object" ||
arguments[i] == null)) {
data = arguments[i++];
}
- if (arguments.length > i && (typeof arguments[i] === "string" ||
arguments[i] == null)) {
- parentId = arguments[i++];
+ if (arguments.length > i && typeof arguments[i] === "boolean") {
+ updateVisualMappers = arguments[i++];
}
- if (arguments.length > i && typeof arguments[i] === "boolean") {
updateVisualMappers = arguments[i++]; }
-
- var n = this.swf().addNode(x, y, data, parentId,
updateVisualMappers);
+ var n = this.swf().addNode(x, y, data, updateVisualMappers);
return this._parseJSON(n);
},
@@ -2481,7 +2483,8 @@
* <li><code>Circle</code></li>
* <li><code>Radial</code></li>
* <li><code>Tree</code></li>
- * <li><code>Preset</code></li></ul>
+ * <li><code>Preset</code></li>
+ * <li><code>CompoundSpringEmbedder</code>: use this option when the
network is a compound graph</li></ul>
* @property
* @name name
* @type String
Modified: cytoscapeweb/branches/compound/html-template/sample.html
===================================================================
--- cytoscapeweb/branches/compound/html-template/sample.html 2011-10-12
21:17:32 UTC (rev 27145)
+++ cytoscapeweb/branches/compound/html-template/sample.html 2011-10-12
21:53:07 UTC (rev 27146)
@@ -34,7 +34,7 @@
//size: "auto",//{ defaultValue: 20, continuousMapper:
{ attrName: "weight", minValue: 20, maxValue: 40 } },
borderWidth: 2,
borderColor: "#707070",
- //image:
"http://chart.apis.google.com/chart?chs=300x300&cht=p&chd=e0:U-gh..bR",
+ image:
"http://chart.apis.google.com/chart?chs=300x300&cht=p&chd=e0:U-gh..bR",
//compoundImage:
"http://chart.apis.google.com/chart?chxr=0,0,160&chxt=x&chbh=a&chs=440x220&cht=bhs&chco=4D89F9,C6D9FD&chd=s:GflxYlS,fl9YSYS",
labelFontSize: { defaultValue: 12, continuousMapper: {
attrName: "weight", minValue: 10, maxValue: 24 } },
tooltipText: { customMapper: { functionName:
"onNodeTooltip" } },
@@ -116,6 +116,7 @@
vis.ready(function() {
showElapsedTime();
+
var layout = vis.layout();
$("#layouts").val(layout.name);
$("input, select").attr("disabled", false);
@@ -141,7 +142,7 @@
x += Math.random() * (evt.target.width/2) *
(Math.round(x)%2==0 ? 1 : -1);
y += Math.random() * (evt.target.height/2) *
(Math.round(y)%2==0 ? 1 : -1);
}
- var n = vis.addNode(x, y, { weight: Math.random(),
label: "NEW" }, parentId, true);
+ var n = vis.addNode(x, y, { weight: Math.random(),
label: "NEW", parent: parentId }, true);
})
.addContextMenuItem("Add new edge", "nodes", function(evt)
{
_srcId = evt.target.data.id;
Modified:
cytoscapeweb/branches/compound/src/org/cytoscapeweb/model/GraphProxy.as
===================================================================
--- cytoscapeweb/branches/compound/src/org/cytoscapeweb/model/GraphProxy.as
2011-10-12 21:17:32 UTC (rev 27145)
+++ cytoscapeweb/branches/compound/src/org/cytoscapeweb/model/GraphProxy.as
2011-10-12 21:53:07 UTC (rev 27146)
@@ -59,9 +59,9 @@
import org.cytoscapeweb.model.data.InteractionVO;
import org.cytoscapeweb.model.data.VisualStyleVO;
import org.cytoscapeweb.model.error.CWError;
+ import org.cytoscapeweb.util.CompoundNodes;
import org.cytoscapeweb.util.ErrorCodes;
import org.cytoscapeweb.util.GraphUtils;
- import org.cytoscapeweb.util.CompoundNodes;
import org.cytoscapeweb.util.Groups;
import org.cytoscapeweb.util.Layouts;
import org.cytoscapeweb.vis.data.CompoundNodeSprite;
@@ -676,17 +676,10 @@
}
normalizeData(data, Groups.NODES);
+ var cns:CompoundNodeSprite = new CompoundNodeSprite();
- // create a new CompoundNodeSprite
- var cns:CompoundNodeSprite = new CompoundNodeSprite();
-
if (data != null) {
cns.data = data;
-
- // init the CompoundNodeSprite if it has a
network field
- if (data.network != null) {
- cns.initialize();
- }
}
// and newly created CompoundNodeSprite to the graph
data, but do
@@ -702,6 +695,22 @@
return cns;
}
+ public function addToParent(ns:NodeSprite,
parent:CompoundNodeSprite):void {
+ var group:DataList = this.graphData.group(Groups.COMPOUND_NODES);
+
+ // initialize the compound node if it is not initialized,
+ // yet. Also, add the compound to the compound node data group
+ if (!parent.isInitialized()) {
+ // initialize child node list
+ parent.initialize();
+ // add to the data group
+ group.add(parent);
+ }
+
+ // add node into the target compound node
+ parent.addNode(ns);
+ }
+
/**
* Resets the missing children array in order to enable
re-calculation
* of missing child nodes in the getter method of
missingChildren.
Modified:
cytoscapeweb/branches/compound/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
===================================================================
---
cytoscapeweb/branches/compound/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
2011-10-12 21:17:32 UTC (rev 27145)
+++
cytoscapeweb/branches/compound/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
2011-10-12 21:53:07 UTC (rev 27146)
@@ -523,23 +523,24 @@
private function parseData(tag:XML, schema:DataSchema):Object {
var data:Object = {};
var name:String, field:DataField, value:Object;
+ var i:int, att:XML;
// set default values
- for (var i:int = 0; i < schema.numFields; ++i) {
+ for (i = 0; i < schema.numFields; ++i) {
field = schema.getFieldAt(i);
data[field.name] = field.defaultValue;
}
// get attribute values
- for each (var attribute:XML in tag.@*) {
- name = attribute.name().toString();
+ for each (att in tag.@*) {
+ name = att.name().toString();
field = schema.getFieldByName(name);
if (field != null)
- data[name] = parseAttValue(attribute[0].toString(),
field.type);
+ data[name] = parseAttValue(att[0].toString(), field.type);
}
// get "att" tags:
- for each (var att:XML in tag.att) {
+ for each (att in tag.att) {
parseAtt(att, schema, data);
}
Modified:
cytoscapeweb/branches/compound/src/org/cytoscapeweb/util/CompoundNodes.as
===================================================================
--- cytoscapeweb/branches/compound/src/org/cytoscapeweb/util/CompoundNodes.as
2011-10-12 21:17:32 UTC (rev 27145)
+++ cytoscapeweb/branches/compound/src/org/cytoscapeweb/util/CompoundNodes.as
2011-10-12 21:53:07 UTC (rev 27146)
@@ -400,7 +400,6 @@
if (ns != null) {
parentId = ns.data.parent;
- //for each (var ns:NodeSprite in cns.getNodes())
while (parentId != null) {
// get parent
parent = graphProxy.getNode(parentId);
@@ -424,8 +423,12 @@
parents.push(parent);
}
- // advance to next node
- parentId = parent.data.parent;
+ // advance to next node (avoid circular
dependencies)
+ if (parent.data.parent !== ns.data.id) {
+ parentId = parent.data.parent;
+ } else {
+ parentId = null;
+ }
}
}
Modified:
cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/ExternalMediator.as
===================================================================
---
cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/ExternalMediator.as
2011-10-12 21:17:32 UTC (rev 27145)
+++
cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/ExternalMediator.as
2011-10-12 21:53:07 UTC (rev 27146)
@@ -400,11 +400,10 @@
newElement.y = p.y;
// check if current node will
be added into a compound
- if (o.parent != null) {
+ if (o.data != null &&
o.data.parent) {
// hold a reference for
the new created sprite
// for fast access
during compound node update
o.sprite = newElement;
-
// add to the list of
child nodes to be added
childrenToAdd.push(o);
}
@@ -425,16 +424,20 @@
newAll.push(newElement);
}
+ // process child nodes to add, and update
corresponding parent compound nodes
+ for each (o in childrenToAdd) {
+ parent =
this.graphProxy.getNode(o.data.parent);
+ this.graphProxy.addToParent(o.sprite,
parent);
+ }
+
// Set listeners, styles, etc:
- graphMediator.initialize(Groups.NODES,
newNodes);
- graphMediator.initialize(Groups.EDGES,
newEdges);
+ graphMediator.initialize(Groups.NODES, newNodes);
+ graphMediator.initialize(Groups.EDGES, newEdges);
- // process child nodes to add, and update
corresponding parent
- // compound nodes
for each (o in childrenToAdd) {
- parent =
this.graphProxy.getNode(o.parent);
-
this.graphMediator.updateCompoundNode(parent, o.sprite);
- }
+ parent = this.graphProxy.getNode(o.data.parent);
+ this.graphMediator.updateCompoundNode(parent, o.sprite);
+ }
// Do it before converting the Nodes/Edges to
plain objects,
// in order to get the rendered visual
properties:
@@ -459,9 +462,12 @@
return JSON.encode(ret);
}
- private function addNode(x:Number, y:Number, data:Object,
- parentId:String=null,
updateVisualMappers:Boolean=false):String {
+ private function addNode(x:Number,
+ y:Number,
+ data:Object,
+
updateVisualMappers:Boolean=false):String {
var extObj:Object = null;
+ var parentId:String = data != null ? data.parent : null;
try {
// create node (always create a CompoundNode
instance)
@@ -476,8 +482,8 @@
// set listeners, styles, etc.
if (ns.isInitialized()) {
- // initialize the node as a compound
node
-
this.graphMediator.initialize(Groups.COMPOUND_NODES, [ns]);
+// // initialize the node as a compound
node
+//
this.graphMediator.initialize(Groups.COMPOUND_NODES, [ns]);
} else {
// initialize the node as a
non-compound node
this.graphMediator.initialize(Groups.NODES, [ns]);
@@ -485,6 +491,7 @@
// update parent compound node if adding a node
to another one
if (parent != null) {
+ this.graphProxy.addToParent(ns, parent);
this.graphMediator.updateCompoundNode(parent, ns);
}
Modified:
cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/GraphMediator.as
===================================================================
--- cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/GraphMediator.as
2011-10-12 21:17:32 UTC (rev 27145)
+++ cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/GraphMediator.as
2011-10-12 21:53:07 UTC (rev 27146)
@@ -30,7 +30,6 @@
package org.cytoscapeweb.view {
import flare.animate.Parallel;
import flare.display.DirtySprite;
- import flare.display.TextSprite;
import flare.util.Arrays;
import flare.vis.data.Data;
import flare.vis.data.DataList;
@@ -297,7 +296,11 @@
}
public function initialize(gr:String, items:Array):void {
- // Set properties:
+ addListeners(items);
+ updateDataSprites(gr, items)
+ }
+
+ public function updateDataSprites(gr:String, items:Array):void {
var props:Object;
if (gr === Groups.NODES) {
@@ -313,7 +316,6 @@
}
vis.updateLabels(gr);
- addListeners(items);
separateDisconnected();
}
@@ -360,22 +362,9 @@
*/
public function updateCompoundNode(parent:CompoundNodeSprite,
ns:NodeSprite):void {
if (parent != null) {
- var group:DataList =
this.graphProxy.graphData.group(Groups.COMPOUND_NODES);
+ // initialize visual properties
+ this.updateDataSprites(Groups.COMPOUND_NODES, [parent]);
- // initialize the compound node if it is not
initialized,
- // yet. Also, add the compound to the compound
node data group
- if (!parent.isInitialized()) {
- // initialize visual properties
- this.initialize(Groups.COMPOUND_NODES,
[parent]);
- // initialize child node list
- parent.initialize();
- // add to the data group
- group.add(parent);
- }
-
- // add node into the target compound node
- parent.addNode(ns);
-
// update bounds of the target compound node up
to the root
while (parent != null) {
// update the bounds of the compound
node
Modified:
cytoscapeweb/branches/compound/src/org/cytoscapeweb/vis/data/CompoundNodeSprite.as
===================================================================
---
cytoscapeweb/branches/compound/src/org/cytoscapeweb/vis/data/CompoundNodeSprite.as
2011-10-12 21:17:32 UTC (rev 27145)
+++
cytoscapeweb/branches/compound/src/org/cytoscapeweb/vis/data/CompoundNodeSprite.as
2011-10-12 21:53:07 UTC (rev 27146)
@@ -32,6 +32,7 @@
import flash.geom.Rectangle;
+ import org.cytoscapeweb.model.error.CWError;
import org.cytoscapeweb.util.Nodes;
/**
@@ -158,14 +159,31 @@
* @param ns child node sprite to be added
*/
public function addNode(ns:NodeSprite):void {
- // check if the node is initialized
- if (this._nodesMap != null) {
- // add the node to the child node list of this
node
- this._nodesMap[ns.data.id] = ns;
- // set the parent id of the added node
- ns.data.parent = this.data.id;
- _nodesCount++;
- }
+ var descendent:CompoundNodeSprite = ns as
CompoundNodeSprite;
+ var stack:Array = [descendent];
+ var id:String = ns.data.id;
+
+ // check for circular dependencies:
+ do {
+ descendent = stack.pop();
+
+ if (descendent.data.id === this.data.parent) {
+ throw new CWError("Cannot add child node '"+ns.data.id+"'
to node '" + this.data.id +
+ "', because it would create a circular
dependency.");
+ }
+
+ for each (descendent in descendent.getNodes()) {
+ stack.push(descendent);
+ }
+ } while (stack.length > 0);
+
+ if (!isInitialized()) initialize();
+
+ // add the node to the child node list of this node
+ this._nodesMap[ns.data.id] = ns;
+ // set the parent id of the added node
+ ns.data.parent = this.data.id;
+ _nodesCount++;
}
/**
--
You received this message because you are subscribed to the Google Groups
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/cytoscape-cvs?hl=en.