Author: clopes Date: 2011-10-14 08:07:33 -0700 (Fri, 14 Oct 2011) New Revision: 27179
Modified: cytoscapeweb/branches/compound/html-template/fixtures/test3.graphml cytoscapeweb/branches/compound/html-template/js/cytoscapeweb.js cytoscapeweb/branches/compound/html-template/js/tests.js cytoscapeweb/branches/compound/src/CytoscapeWeb.mxml cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/ExternalMediator.as Log: Added parentNodes() and childNodes() API functions. Fixed some QUnit tests. Modified: cytoscapeweb/branches/compound/html-template/fixtures/test3.graphml =================================================================== --- cytoscapeweb/branches/compound/html-template/fixtures/test3.graphml 2011-10-14 08:00:50 UTC (rev 27178) +++ cytoscapeweb/branches/compound/html-template/fixtures/test3.graphml 2011-10-14 15:07:33 UTC (rev 27179) @@ -1,10 +1,10 @@ <graphml xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd" xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <key id="name" for="all" attr.name="name" attr.type="string"/> - <key id="weight" for="node" attr.name="weight" attr.type="double"/> + <key id="label" for="all" attr.name="label" attr.type="string"/> + <key id="weight" for="all" attr.name="weight" attr.type="double"/> <key id="ranking" for="node" attr.name="ranking" attr.type="int"/> <key id="type" for="node" attr.name="type" attr.type="string"/> <key id="shape" for="node" attr.name="shape" attr.type="string"/> - <key id="label" for="node" attr.name="label" attr.type="string"/> <key id="special" for="node" attr.name="special" attr.type="boolean"/> <key id="type" for="edge" attr.name="type" attr.type="string"/> <key id="interaction" for="edge" attr.name="interaction" attr.type="string"> Modified: cytoscapeweb/branches/compound/html-template/js/cytoscapeweb.js =================================================================== --- cytoscapeweb/branches/compound/html-template/js/cytoscapeweb.js 2011-10-14 08:00:50 UTC (rev 27178) +++ cytoscapeweb/branches/compound/html-template/js/cytoscapeweb.js 2011-10-14 15:07:33 UTC (rev 27179) @@ -601,21 +601,53 @@ }, /** - * <p>Get all nodes from the network or from another node. + * <p>Get all nodes from the network.</p> + * <p>If the <code>topLevelOnly</code> parameter is <code>true</code>, child nodes are not returned in the list.</p> * In order to retrieve the children of a compound node, simply pass the parent node object or its <code>id</code>.</p> - * @param {Object} [parent] Optional parent node object or ID. If <code>null</code> or undefined, - * it returns all the nodes that exist in the network. - * @return {Array} List of nodes. + * @param {Boolean} [topLevelOnly] It is optional and the default value is <code>false</code>, which means that all existing nodes + are returned as a flat list, no matter whether or not they are regular, child or parent ones. + If <code>false</code>, nodes that are children of other nodes are not included in the list. + * @return {Array} List of {@link org.cytoscapeweb.Node} objects. * @see org.cytoscapeweb.Visualization#edges * @see org.cytoscapeweb.Visualization#node + * @see org.cytoscapeweb.Visualization#parentNodes + * @see org.cytoscapeweb.Visualization#childNodes */ - nodes: function (parent) { - if (parent && typeof parent === "object" && parent.hasOwnProperty("data")) { + nodes: function (topLevelOnly) { + var str = this.swf().getNodes(topLevelOnly); + return this._parseJSON(str); + }, + + /** + * <p>Get all nodes that belong to another node.</p> + * @param {Object} parent The parent node object or the parent ID (String). + * @return {Array} List of {@link org.cytoscapeweb.Node} objects. + * @see org.cytoscapeweb.Visualization#edges + * @see org.cytoscapeweb.Visualization#nodes + * @see org.cytoscapeweb.Visualization#parentNodes + * @see org.cytoscapeweb.Visualization#node + */ + childNodes: function (parent) { + if (parent == null) { throw("The 'parent' parameter is mandatory."); } + if (typeof parent === "object" && parent.hasOwnProperty("data")) { if (typeof parent.data === "object") { parent = parent.data.id; } } - var str = this.swf().getNodes(parent); - return this._parseJSON(str); + var str = this.swf().getChildNodes(parent); + return this._parseJSON(str); }, + + /** + * <p>Get only the compound nodes from the network, if there is any.</p> + * @return {Array} List of {@link org.cytoscapeweb.Node} objects that contain one or more child nodes. + * @see org.cytoscapeweb.Visualization#edges + * @see org.cytoscapeweb.Visualization#nodes + * @see org.cytoscapeweb.Visualization#childNodes + * @see org.cytoscapeweb.Visualization#node + */ + parentNodes: function () { + var str = this.swf().getParentNodes(); + return this._parseJSON(str); + }, /** * <p>Get one edge, including any merged edge, by its unique ID.</p> @@ -1821,7 +1853,7 @@ "quality", "high", "bgcolor", "#ffffff", "name", this.id, - "allowScriptAccess","sameDomain", + "allowScriptAccess","always", "type", "application/x-shockwave-flash", "pluginspage", "http://www.adobe.com/go/getflashplayer" ); Modified: cytoscapeweb/branches/compound/html-template/js/tests.js =================================================================== --- cytoscapeweb/branches/compound/html-template/js/tests.js 2011-10-14 08:00:50 UTC (rev 27178) +++ cytoscapeweb/branches/compound/html-template/js/tests.js 2011-10-14 15:07:33 UTC (rev 27179) @@ -527,8 +527,10 @@ same(s.edges.width.continuousMapper.maxValue, style.edges.width.continuousMapper.maxValue); $.each(nodes, function(i, n) { - same(Math.round(n.opacity*100)/100, s.nodes.opacity, "Node opacity"); - same(n.borderColor, s.nodes.borderColor, "Node borderColor"); + if (n.nodesCount == 0) { // ignore compound nodes + same(Math.round(n.opacity*100)/100, s.nodes.opacity, "Node opacity"); + same(n.borderColor, s.nodes.borderColor, "Node borderColor"); + } }); $.each(edges, function(i, e) { same(Math.round(e.opacity*100)/100, s.edges.opacity, "Edge opacity"); @@ -585,7 +587,11 @@ $.each(nodes, function(i, n) { var o = nodeOpacity(n.data.id); - bypass.nodes[n.data.id] = { opacity: o, color: nodeColor }; + if (n.nodesCount > 0) { + bypass.nodes[n.data.id] = { compoundOpacity: o, compoundColor: nodeColor }; + } else { + bypass.nodes[n.data.id] = { opacity: o, color: nodeColor }; + } }); $.each(edges, function(i, e) { var o = edgeOpacity(e.data.id); @@ -605,11 +611,12 @@ $.each(nodes, function(i, n) { var expected = nodeOpacity(n.data.id); - same(bp.nodes[n.data.id].opacity, expected); same(Math.round(n.opacity*100)/100, expected); - - same(bp.nodes[n.data.id].color, nodeColor); same(n.color, nodeColor); + var opacityAttr = n.nodesCount > 0 ? "compoundOpacity" : "opacity"; + same(bp.nodes[n.data.id][opacityAttr], expected); + var colorAttr = n.nodesCount > 0 ? "compoundColor" : "color"; + same(bp.nodes[n.data.id][colorAttr], nodeColor); }); $.each(edges, function(i, e) { var expected = edgeOpacity(e.data.id); @@ -765,7 +772,7 @@ } }); - // TODO: what happens when filtering merged edges? + // TODO: test filtering merged edges? // NODES: // Filter: @@ -780,7 +787,8 @@ same(fnList.length, 3, "Filtered correct number of nodes"); // Listeners for "nodes" & "none" should get the same results: $.each([fnList, fAllList], function(i, filtered) { - $.each(fnList, function(j, n) { + $.each(filtered, function(j, n) { + n = vis.node(n.data.id); inNodes[n.data.id] = n; same(n.group, "nodes", "Filtered group for '"+n.data.id+"' ("+j+")"); ok(n.data.weight > 0.03 && n.data.weight < 0.4, "Node '"+n.data.id+"' correctly filtered ("+j+")"); @@ -918,7 +926,7 @@ var edges = vis.edges(), nodes = vis.nodes(); var count = edges.length; var e; - var src = nodes[0], tgt = nodes[3]; + var src = nodes[0], tgt = nodes[2]; // 1. NO id: e = vis.addEdge({ source: src.data.id, target: tgt.data.id }); @@ -942,7 +950,7 @@ vis.addDataField("edges", { name: "null_number_attr", type: "number" }); var nodes = vis.nodes(); - var src = nodes[0], tgt = nodes[3]; + var src = nodes[0], tgt = nodes[2]; var e = vis.addEdge({ source: src.data.id, target: tgt.data.id, null_number_attr: null }); same(e.data.null_number_attr, null, "New edge added: 'null_number_attr' still null"); @@ -1018,15 +1026,18 @@ }); // 3. Remove only one by Object: - vis.removeNode(originalNodes[1]); - same(vis.node(originalNodes[1].data.id), null, "Node '"+originalNodes[1].data.id+"' deleted"); + vis.removeNode(originalNodes[0]); + nodesCount -= 1 + originalNodes[0].nodesCount; // in case this node had children + same(vis.node(originalNodes[0].data.id), null, "Node '"+originalNodes[1].data.id+"' deleted"); // 4. Remove 2 nodes - by object: - vis.removeElements("nodes", [originalNodes[2], originalNodes[3]]); + vis.removeElements("nodes", [originalNodes[1], originalNodes[2]]); + nodesCount -= 1 + originalNodes[1].nodesCount; + nodesCount -= 1 + originalNodes[2].nodesCount; nodes = vis.nodes(); - same(nodes.length, nodesCount-4, "2 more nodes removed - new length"); + same(nodes.length, nodesCount, "2 more nodes removed - new length"); + same(vis.node(originalNodes[1].data.id), null, "Node '"+originalNodes[1].data.id+"' deleted"); same(vis.node(originalNodes[2].data.id), null, "Node '"+originalNodes[2].data.id+"' deleted"); - same(vis.node(originalNodes[3].data.id), null, "Node '"+originalNodes[3].data.id+"' deleted"); // 5. Remove ALL: vis.removeElements(); @@ -1321,9 +1332,10 @@ var edges = vis.edges(); var schema = vis.dataSchema(); var ignoredFields = 5; // id (nodes), id (edges), source, target, directed + var parents = vis.parentNodes(); same(xml[0].tagName.toLowerCase(), "graphml", "<graphml> tag"); - same(xml.find("graph").length, 1, "<graph> tag"); + same(xml.find("graph").length, parents.length + 1, "<graph> tag"); same(xml.find("key").length, (schema.nodes.length + schema.edges.length - ignoredFields), "Number <key> tags"); same(xml.find("node").length, nodes.length, "Number of nodes"); same(xml.find("edge").length, edges.length, "Number of edges"); @@ -1333,8 +1345,10 @@ var xml = $(vis.xgmml()); var nodes = vis.nodes(); var edges = vis.edges(); + var parents = vis.parentNodes();console.log(xml) same(xml[0].tagName.toLowerCase(), "graph", "<graph> tag"); + same(xml.find("att graph").length, parents.length, "nested <graph> tags"); // compound graphs only same(xml.find("node").length, nodes.length, "Number of nodes"); same(xml.find("node graphics").length, nodes.length, "Number of node graphics"); same(xml.find("edge").length, edges.length, "Number of edges"); @@ -1380,11 +1394,12 @@ var p = $("#"+vis.containerId).coordinates(); var scale = vis.zoom(); - var size = n.size * scale; + var w = n.width * scale; + var h = n.height * scale; p.x += n.x; p.y += n.y; - pointer.css('left', p.x - size/2).css('top', p.y - size/2); - pointer.css('width', size).css('height', size); + pointer.css('left', p.x - w/2).css('top', p.y - h/2); + pointer.css('width', w).css('height', h); }); }); vis.zoomToFit(); Modified: cytoscapeweb/branches/compound/src/CytoscapeWeb.mxml =================================================================== --- cytoscapeweb/branches/compound/src/CytoscapeWeb.mxml 2011-10-14 08:00:50 UTC (rev 27178) +++ cytoscapeweb/branches/compound/src/CytoscapeWeb.mxml 2011-10-14 15:07:33 UTC (rev 27179) @@ -46,6 +46,8 @@ public var graphView:GraphView; private function onInit():void { + Security.allowDomain("*"); + // Create and add the View that contains the GRAPH: graphView = new GraphView(); graphBox.addChild(graphView); Modified: cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/ExternalMediator.as =================================================================== --- cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/ExternalMediator.as 2011-10-14 08:00:50 UTC (rev 27178) +++ cytoscapeweb/branches/compound/src/org/cytoscapeweb/view/ExternalMediator.as 2011-10-14 15:07:33 UTC (rev 27179) @@ -32,6 +32,7 @@ import flare.data.DataSchema; import flare.data.DataSet; + import flare.vis.data.DataList; import flare.vis.data.DataSprite; import flare.vis.data.EdgeSprite; import flare.vis.data.NodeSprite; @@ -303,23 +304,42 @@ return JSON.encode(obj); } - private function getNodes(parentId:String=null):String { - var nodes:*, arr:Array = []; + private function getNodes(topLevelOnly:Boolean):String { + var nodes:* = graphProxy.graphData.nodes; + var arr:*, n:NodeSprite; - if (parentId != null) { - var cn:CompoundNodeSprite = graphProxy.getNode(parentId); - if (cn != null) nodes = cn.getNodes(); + if (topLevelOnly) { + arr = []; + for each (n in nodes) { + if (n.data.parent == null) arr.push(n); + } } else { - // TODO: return only top-level nodes (no children)? - nodes = graphProxy.graphData.nodes; + arr = nodes != null ? nodes : []; } + arr = ExternalObjectConverter.toExtElementsArray(arr, graphProxy.zoom); + return JSON.encode(arr); + } + + private function getChildNodes(parentId:String):String { + var nodes:*, arr:Array = []; + var cn:CompoundNodeSprite = graphProxy.getNode(parentId); + + if (cn != null) + nodes = cn.getNodes(); if (nodes != null) arr = ExternalObjectConverter.toExtElementsArray(nodes, graphProxy.zoom); return JSON.encode(arr); } + private function getParentNodes():String { + var nodes:DataList = graphProxy.graphData.group(Groups.COMPOUND_NODES); + var list:* = nodes != null ? nodes : []; + list = ExternalObjectConverter.toExtElementsArray(list, graphProxy.zoom); + return JSON.encode(list); + } + private function getEdges():String { var edges:Array = graphProxy.edges; var arr:Array = ExternalObjectConverter.toExtElementsArray(edges, graphProxy.zoom); @@ -691,7 +711,8 @@ "zoomTo", "zoomToFit", "getZoom", "filter", "removeFilter", "firstNeighbors", - "getNodes", "getEdges", "getMergedEdges", + "getNodes", "getParentNodes", "getChildNodes", + "getEdges", "getMergedEdges", "getNodeById", "getEdgeById", "getSelectedNodes", "getSelectedEdges", "getLayout", "applyLayout", -- 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.
