Author: clopes
Date: 2011-09-23 14:26:36 -0700 (Fri, 23 Sep 2011)
New Revision: 26957

Modified:
   cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js
   cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js
   
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/ExternalObjectConverterTest.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DeselectCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/ExportNetworkCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/FilterCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/HandleClickCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/HandleHoverCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/RemoveFilterCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SelectCommand.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/GraphProxy.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/ExternalObjectConverter.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/data/FirstNeighborsVO.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/GraphUtils.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ContextMenuMediator.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/GraphMediator.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphView.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphVis.as
Log:
Fixed #2590: XGMML: Restore and save view center correctly.
Added rawX and rawY to Node.
Return networkModel to JS as JSON, in order to prevent errors with special 
chars.

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js    
2011-09-23 20:31:57 UTC (rev 26956)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js    
2011-09-23 21:26:36 UTC (rev 26957)
@@ -1266,7 +1266,8 @@
          * @see org.cytoscapeweb.Visualization#sif
          */
         networkModel: function () {
-            return this.swf().getNetworkModel();
+               var json = this.swf().getNetworkModel();
+            return this._parseJSON(json);
         },
         
         /**

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js   2011-09-23 
20:31:57 UTC (rev 26956)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js   2011-09-23 
21:26:36 UTC (rev 26957)
@@ -1036,7 +1036,7 @@
        
        // Exporting data/image should not throw errors:
        ok(vis.pdf().indexOf("JVBERi0xLjUKMSAwIG9iago8PC9UeXBlIC9QYWd") === 0, 
"PDF image");
-       ok(vis.png().indexOf("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAA") === 0, 
"PNG image");
+       ok(vis.png().indexOf("iVBORw0KGgoAAAANSUhEUgAAAA") === 0, "PNG image");
        
        same(vis.sif(), "", "SIF is empty");
        

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DeselectCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DeselectCommand.as
  2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/DeselectCommand.as
  2011-09-23 21:26:36 UTC (rev 26957)
@@ -69,7 +69,7 @@
                 var objs:Array, body:Object, type:String = "deselect";
                 
                 if (nodes.length > 0 && extMediator.hasListener(type, 
Groups.NODES)) {
-                    objs = ExternalObjectConverter.toExtElementsArray(nodes);
+                    objs = ExternalObjectConverter.toExtElementsArray(nodes, 
graphProxy.zoom);
                     body = { functionName: ExternalFunctions.INVOKE_LISTENERS, 
                              argument: { type: type, group: Groups.NODES, 
target: objs } };
                     
@@ -77,7 +77,7 @@
                 }
                 
                 if (edges.length > 0 && extMediator.hasListener(type, 
Groups.EDGES)) {
-                    objs = ExternalObjectConverter.toExtElementsArray(edges);
+                    objs = ExternalObjectConverter.toExtElementsArray(edges, 
graphProxy.zoom);
                     body = { functionName: ExternalFunctions.INVOKE_LISTENERS, 
                              argument: { type: type, group: Groups.EDGES, 
target: objs } };
 
@@ -89,7 +89,7 @@
                     all = all.concat(nodes).concat(edges);
                     
                     if (all.length > 0) {
-                        objs = ExternalObjectConverter.toExtElementsArray(all);
+                        objs = ExternalObjectConverter.toExtElementsArray(all, 
graphProxy.zoom);
                         body = { functionName: 
ExternalFunctions.INVOKE_LISTENERS, 
                                  argument: { type: type, group: Groups.NONE, 
target: objs } };
     

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/ExportNetworkCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/ExportNetworkCommand.as
     2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/ExportNetworkCommand.as
     2011-09-23 21:26:36 UTC (rev 26957)
@@ -28,6 +28,8 @@
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
 package org.cytoscapeweb.controller {
+    import flash.geom.Point;
+    
     import mx.utils.StringUtil;
     
     import org.cytoscapeweb.model.methods.error;
@@ -55,7 +57,8 @@
                     data = appMediator.getGraphImage(format, w, h);
                 } else {
                     // Get the text:
-                    data = graphProxy.getDataAsText(format, options);
+                    var viewCenter:Point = graphMediator.getViewCenter();
+                    data = graphProxy.getDataAsText(format, viewCenter, 
options);
                 }
                 
                 // Export:

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/FilterCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/FilterCommand.as
    2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/FilterCommand.as
    2011-09-23 21:26:36 UTC (rev 26957)
@@ -79,7 +79,7 @@
                     var objs:Array, body:Object, type:String = "filter";
                 
                     if (nodes != null && extMediator.hasListener(type, 
Groups.NODES)) {
-                        objs = 
ExternalObjectConverter.toExtElementsArray(nodes);
+                        objs = 
ExternalObjectConverter.toExtElementsArray(nodes, graphProxy.zoom);
                         body = { functionName: 
ExternalFunctions.INVOKE_LISTENERS, 
                                  argument: { type: type, group: Groups.NODES, 
target: objs } };
                         
@@ -87,7 +87,7 @@
                     }
                     
                     if (edges != null && extMediator.hasListener(type, 
Groups.EDGES)) {
-                        objs = 
ExternalObjectConverter.toExtElementsArray(edges);
+                        objs = 
ExternalObjectConverter.toExtElementsArray(edges, graphProxy.zoom);
                         body = { functionName: 
ExternalFunctions.INVOKE_LISTENERS, 
                                  argument: { type: type, group: Groups.EDGES, 
target: objs } };
     
@@ -95,7 +95,7 @@
                     }
                     
                     if ((nodes != null || edges != null) && 
extMediator.hasListener(type, Groups.NONE)) {
-                        objs = ExternalObjectConverter.toExtElementsArray(arr);
+                        objs = ExternalObjectConverter.toExtElementsArray(arr, 
graphProxy.zoom);
                         body = { functionName: 
ExternalFunctions.INVOKE_LISTENERS, 
                                  argument: { type: type, group: Groups.NONE, 
target: objs } };
     

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/HandleClickCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/HandleClickCommand.as
       2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/HandleClickCommand.as
       2011-09-23 21:26:36 UTC (rev 26957)
@@ -60,7 +60,7 @@
             
             // Call external listener:            
             if (extMediator.hasListener(type, group)) {
-                var target:Object = ExternalObjectConverter.toExtElement(ds);
+                var target:Object = ExternalObjectConverter.toExtElement(ds, 
graphProxy.zoom);
                 
                 body = { functionName: ExternalFunctions.INVOKE_LISTENERS, 
                          argument: { type: type,

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/HandleHoverCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/HandleHoverCommand.as
       2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/HandleHoverCommand.as
       2011-09-23 21:26:36 UTC (rev 26957)
@@ -79,7 +79,7 @@
                 
             // Call external listener:            
             if (extMediator.hasListener(type, group)) {
-                var target:Object = ExternalObjectConverter.toExtElement(ds);
+                var target:Object = ExternalObjectConverter.toExtElement(ds, 
graphProxy.zoom);
 
                 var body:Object = { functionName: 
ExternalFunctions.INVOKE_LISTENERS, 
                                     argument: { type: type, group: group, 
target: target } };

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/RemoveFilterCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/RemoveFilterCommand.as
      2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/RemoveFilterCommand.as
      2011-09-23 21:26:36 UTC (rev 26957)
@@ -95,7 +95,7 @@
                         if (fe != null) all = all.concat(fe);
                     }
     
-                    objs = ExternalObjectConverter.toExtElementsArray(all);
+                    objs = ExternalObjectConverter.toExtElementsArray(all, 
graphProxy.zoom);
                     body = { functionName: ExternalFunctions.INVOKE_LISTENERS, 
                              argument: { type: type, group: Groups.NONE, 
target: objs } };
     

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SelectCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SelectCommand.as
    2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SelectCommand.as
    2011-09-23 21:26:36 UTC (rev 26957)
@@ -67,7 +67,7 @@
                 var objs:Array, body:Object, type:String = "select";
                 
                 if (nodes.length > 0 && extMediator.hasListener(type, 
Groups.NODES)) {
-                    objs = ExternalObjectConverter.toExtElementsArray(nodes);
+                    objs = ExternalObjectConverter.toExtElementsArray(nodes, 
graphProxy.zoom);
                     body = { functionName: ExternalFunctions.INVOKE_LISTENERS, 
                              argument: { type: type, group: Groups.NODES, 
target: objs } };
                     
@@ -75,7 +75,7 @@
                 }
                 
                 if (edges.length > 0 && extMediator.hasListener(type, 
Groups.EDGES)) {
-                    objs = ExternalObjectConverter.toExtElementsArray(edges);
+                    objs = ExternalObjectConverter.toExtElementsArray(edges, 
graphProxy.zoom);
                     body = { functionName: ExternalFunctions.INVOKE_LISTENERS, 
                              argument: { type: type, group: Groups.EDGES, 
target: objs } };
 
@@ -86,7 +86,7 @@
                     var all:Array = [];
                     all = all.concat(nodes).concat(edges);
 
-                    objs = ExternalObjectConverter.toExtElementsArray(all);
+                    objs = ExternalObjectConverter.toExtElementsArray(all, 
graphProxy.zoom);
                     body = { functionName: ExternalFunctions.INVOKE_LISTENERS, 
                              argument: { type: type, group: Groups.NONE, 
target: objs } };
 

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/GraphProxy.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/GraphProxy.as    
2011-09-23 20:31:57 UTC (rev 26956)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/GraphProxy.as    
2011-09-23 21:26:36 UTC (rev 26957)
@@ -39,6 +39,8 @@
        import flare.vis.data.EdgeSprite;
        import flare.vis.data.NodeSprite;
        
+       import flash.geom.Point;
+       import flash.geom.Rectangle;
        import flash.net.URLRequest;
        import flash.net.URLRequestHeader;
        import flash.net.URLRequestMethod;
@@ -58,6 +60,7 @@
        import org.cytoscapeweb.model.data.VisualStyleVO;
        import org.cytoscapeweb.model.error.CWError;
        import org.cytoscapeweb.util.ErrorCodes;
+       import org.cytoscapeweb.util.GraphUtils;
        import org.cytoscapeweb.util.Groups;
        import org.cytoscapeweb.util.Layouts;
        import org.puremvc.as3.patterns.proxy.Proxy;
@@ -84,6 +87,8 @@
         
         /** Scale factor, between 0 and 1 */
         private var _zoom:Number = 1;
+        /** The viewport center */
+        private var _viewCenter:Point;
 
         private var _configProxy:ConfigProxy;
         
@@ -301,6 +306,14 @@
         public function set zoom(value:Number):void {
             _zoom = value;
         }
+        
+        public function get viewCenter():Point {
+            return _viewCenter;
+        }
+ 
+        public function set viewCenter(value:Point):void {
+            _viewCenter = value;
+        }
 
         // ========[ CONSTRUCTOR 
]==================================================================
 
@@ -717,6 +730,7 @@
                             ds = xgmmlConverter.parse(xml);
                             
                             this.zoom = xgmmlConverter.zoom;
+                            this.viewCenter = xgmmlConverter.viewCenter;
                             
                             var points:Object = xgmmlConverter.points;
                             if (points != null) {
@@ -750,7 +764,9 @@
             }
         }
         
-        public function getDataAsText(format:String="xgmml", 
options:Object=null):String {
+        public function getDataAsText(format:String="xgmml",
+                                      viewCenter:Point=null,
+                                      options:Object=null):String {
             var out:IDataOutput, nodesTable:DataTable, edgesTable:DataTable, 
dtSet:DataSet;
             format = StringUtil.trim(format.toLowerCase());
                         
@@ -758,7 +774,10 @@
                 nodesTable = new GraphicsDataTable(graphData.nodes, 
nodesSchema);
                 edgesTable = new 
GraphicsDataTable(graphData.group(Groups.REGULAR_EDGES), edgesSchema);
                 dtSet = new DataSet(nodesTable, edgesTable);
-                out = new XGMMLConverter(configProxy.visualStyle).write(dtSet);
+                var bounds:Rectangle = GraphUtils.getBounds(nodes, edges,
+                                                            
!configProxy.nodeLabelsVisible,
+                                                            
!configProxy.edgeLabelsVisible);
+                out = new XGMMLConverter(configProxy.visualStyle, zoom, 
viewCenter, bounds).write(dtSet);
             } else {
                 nodesTable = new DataTable(graphData.nodes.toDataArray(), 
nodesSchema);
                 edgesTable = new 
DataTable(graphData.group(Groups.REGULAR_EDGES).toDataArray(), edgesSchema);

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/ExternalObjectConverter.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/ExternalObjectConverter.as
    2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/ExternalObjectConverter.as
    2011-09-23 21:26:36 UTC (rev 26957)
@@ -216,21 +216,24 @@
             return obj;
         }
         
-        public static function toExtElementsArray(dataSprites:*):Array {
+        public static function toExtElementsArray(dataSprites:*, 
zoom:Number):Array {
             var arr:Array = null;
                      
             if (dataSprites is DataList || dataSprites is Array) {
                 arr = [];
                 for each (var ds:DataSprite in dataSprites) {
-                    arr.push(toExtElement(ds));
+                    arr.push(toExtElement(ds, zoom));
                 }
             }
 
             return arr;
         }
         
-        public static function toExtElement(ds:DataSprite):Object {
+        public static function toExtElement(ds:DataSprite, zoom:Number):Object 
{
             var obj:Object = null;
+            var p:Point;
+            var n:NodeSprite, e:EdgeSprite;
+            var scale:Number;
 
             if (ds != null) {
                 // Data (attributes):
@@ -241,7 +244,8 @@
                 obj.visible = ds.visible;
                 
                 if (ds is NodeSprite) {
-                    var n:NodeSprite = NodeSprite(ds);
+                    n = ds as NodeSprite;
+                    
                     obj.group = Groups.NODES;
                     obj.shape = n.shape;
                     obj.size = Math.max(n.width, n.height);
@@ -255,13 +259,16 @@
 //                    obj.outdegree = n.outDegree;
                     
                     // Global coordinates:
-                    var p:Point = getGlobalCoordinate(ds as NodeSprite);
+                    p = getGlobalCoordinate(n);
                     obj.x = p.x;
                     obj.y = p.y;
+                    
+                    obj.rawX = p.x / zoom;
+                    obj.rawY = p.y / zoom;
                 } else {
                     obj.group = Groups.EDGES;
 
-                    var e:EdgeSprite = EdgeSprite(ds);
+                    e = EdgeSprite(ds);
                     obj.color = Utils.rgbColorAsString(e.lineColor);
                     obj.width = ds.lineWidth;
                     obj.sourceArrowShape = e.props.sourceArrowShape;
@@ -273,7 +280,7 @@
                     
                     if (e.props.$merged) {
                         var ee:Array = e.props.$edges;
-                        ee = toExtElementsArray(ee);
+                        ee = toExtElementsArray(ee, zoom);
                         obj.edges = ee;
                     }
                 }
@@ -285,6 +292,7 @@
         public static function getGlobalCoordinate(n:NodeSprite):Point {
             var p:Point = new Point(n.x, n.y);
             if (n.parent) p = n.parent.localToGlobal(p);
+            
             return p;
         }
         

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
     2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/XGMMLConverter.as
     2011-09-23 21:26:36 UTC (rev 26957)
@@ -39,6 +39,7 @@
     import flare.vis.data.NodeSprite;
     
     import flash.geom.Point;
+    import flash.geom.Rectangle;
     import flash.utils.ByteArray;
     import flash.utils.IDataInput;
     import flash.utils.IDataOutput;
@@ -46,8 +47,6 @@
     import mx.formatters.DateFormatter;
     import mx.utils.StringUtil;
     
-    import org.cytoscapeweb.ApplicationFacade;
-    import org.cytoscapeweb.model.GraphProxy;
     import org.cytoscapeweb.model.data.DiscreteVizMapperVO;
     import org.cytoscapeweb.model.data.GraphicsDataTable;
     import org.cytoscapeweb.model.data.VisualPropertyVO;
@@ -195,12 +194,10 @@
         
         private var _noGraphicInfo:Boolean = false;
         private var _style:VisualStyleVO;
+        private var _zoom:Number;
+        private var _viewCenter:Point;
+        private var _bounds:Rectangle;
         private var _points:Array;
-        private var _minX:Number = Number.POSITIVE_INFINITY;
-        private var _minY:Number = Number.POSITIVE_INFINITY;
-        private var _maxX:Number = Number.NEGATIVE_INFINITY
-        private var _maxY:Number = Number.NEGATIVE_INFINITY;
-        private var _scale:Number = 1;
         
         private function get dateFormatter():DateFormatter {
             var dtf:DateFormatter = new DateFormatter();
@@ -208,26 +205,32 @@
             return dtf;
         }
         
-        private var graphProxy:GraphProxy = 
ApplicationFacade.getInstance().retrieveProxy(GraphProxy.NAME) as GraphProxy;
-        
         // ========[ PUBLIC PROPERTIES 
]============================================================
    
         public function get zoom():Number {
-            return _scale;
+            return _zoom;
         }
    
         public function get style():VisualStyleVO {
             return _style;
         }
         
+        public function get viewCenter():Point {
+            return _viewCenter;
+        }
+        
         public function get points():Array {
             return _points;
         }
    
         // ========[ CONSTRUCTOR 
]==================================================================
         
-        public function XGMMLConverter(style:VisualStyleVO) {
+        public function XGMMLConverter(style:VisualStyleVO, zoom:Number=1,
+                                       viewCenter:Point=null, 
bounds:Rectangle= null) {
                _style = style;
+               _zoom = zoom;
+               _viewCenter = viewCenter;
+               _bounds = bounds;
         }
         
         // ========[ PUBLIC METHODS 
]===============================================================
@@ -290,9 +293,21 @@
             }
             
             var scale:* = xgmml.att.(@name == "GRAPH_VIEW_ZOOM").@value[0];
-            _scale = scale != null ? new Number(scale.toString()) : 1.0;
-            if (isNaN(_scale)) _scale = 1.0;
+            _zoom = scale != null ? new Number(scale.toString()) : 1.0;
+            if (isNaN(_zoom)) _zoom = 1.0;
             
+            var vx:* = xgmml.att.(@name == "GRAPH_VIEW_CENTER_X").@value[0];
+            var vy:* = xgmml.att.(@name == "GRAPH_VIEW_CENTER_Y").@value[0];
+            
+            if (vx != null && vy != null) {
+                vx = new Number(vx.toString());
+                vy = new Number(vy.toString());
+                
+                if (!isNaN(vx) && !isNaN(vy)) {
+                    _viewCenter = new Point(vx, vy);
+                }
+            }
+            
             // Parse nodes
             // ------------------------------------------------------
             var nodesList:XMLList = xgmml.node;
@@ -355,7 +370,6 @@
         /** @inheritDoc */
         public function write(dtset:DataSet, 
output:IDataOutput=null):IDataOutput {
                var bgColor:uint = 
style.getValue(VisualProperties.BACKGROUND_COLOR) as uint;
-               _scale = graphProxy.zoom;
                
             // Init XGMML:
             var xgmml:XML = 
@@ -384,23 +398,19 @@
                     </att>
 -->
                                        <att type="string" 
name="backgroundColor" value={Utils.rgbColorAsString(bgColor)}/>
-                                       <att type="real" name="GRAPH_VIEW_ZOOM" 
value={_scale}/>
-                                       <att type="real" 
name="GRAPH_VIEW_CENTER_X" value="0"/>
-                                       <att type="real" 
name="GRAPH_VIEW_CENTER_Y" value="0"/>
+                                       <att type="real" name="GRAPH_VIEW_ZOOM" 
value={zoom}/>
                 </graph>;
             
+            // View center:
+            if (viewCenter != null) {
+                xgmml.appendChild(<att type="real" name="GRAPH_VIEW_CENTER_X" 
value={viewCenter.x}/>);
+                xgmml.appendChild(<att type="real" name="GRAPH_VIEW_CENTER_Y" 
value={viewCenter.y}/>);
+            }
+            
             // Add edge and node tags:
             addTags(xgmml, dtset, NODE);
             addTags(xgmml, dtset, EDGE);
             
-            // To center the view:
-            var w:Number = (_minX + (_maxX - _minX)/2)/_scale;
-            var h:Number = (_minY + (_maxY - _minY)/2)/_scale;
-            if (w != Infinity && w != -Infinity)
-                xgmml.att.(@name == "GRAPH_VIEW_CENTER_X").@value = w;
-            if (h != Infinity && h != -Infinity)
-                xgmml.att.(@name == "GRAPH_VIEW_CENTER_Y").@value = h;
-            
             // Return output:
             if (output == null) output = new ByteArray();
             output.writeUTFBytes(xgmml.toXMLString());
@@ -433,8 +443,6 @@
                parseAtt(att, schema, data);
             }
             
-            // TODO: get RDF (Resource Description Framework) ???
-            
             return data;
         }
         
@@ -516,6 +524,7 @@
             var attrs:Object;
             var graphAttrs:Object;
             var table:DataTable;
+            var nx:Number, ny:Number;
             
             if (tagName == NODE) {
                table = dtset.nodes;
@@ -560,16 +569,16 @@
                     // Node position:
                     if (ds is NodeSprite) {
                         var n:NodeSprite = ds as NodeSprite;
-                        p = ExternalObjectConverter.getGlobalCoordinate(n);
-                        graphics.@x = p.x / _scale;
-                        graphics.@y = p.y / _scale;
+                        nx = n.x;
+                        ny = n.y;
                         
-                        // For centering the network view:
-                        var ns:Number = n.height;
-                        _minX = Math.min(_minX, (p.x - ns/2));
-                        _minY = Math.min(_minY, (p.y - ns/2));
-                        _maxX = Math.max(_maxX, (p.x + ns/2));
-                        _maxY = Math.max(_maxY, (p.y + ns/2));
+                        if (_bounds != null) {
+                            nx -= _bounds.x;
+                            ny -= _bounds.y;
+                        }
+                        
+                        graphics.@x = nx;
+                        graphics.@y = ny;
                     }
                     
                     // Styles (color, width...):

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/data/FirstNeighborsVO.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/data/FirstNeighborsVO.as
 2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/data/FirstNeighborsVO.as
 2011-09-23 21:26:36 UTC (rev 26957)
@@ -150,13 +150,13 @@
             return _map[n] === false;
         }
         
-        public function toObject():Object {
+        public function toObject(zoom:Number):Object {
             var obj:Object = {};
             
-            obj.rootNodes = 
ExternalObjectConverter.toExtElementsArray(rootNodes);
-            obj.neighbors = 
ExternalObjectConverter.toExtElementsArray(neighbors);
-            obj.edges = ExternalObjectConverter.toExtElementsArray(edges);
-            obj.mergedEdges = 
ExternalObjectConverter.toExtElementsArray(mergedEdges);
+            obj.rootNodes = 
ExternalObjectConverter.toExtElementsArray(rootNodes, zoom);
+            obj.neighbors = 
ExternalObjectConverter.toExtElementsArray(neighbors, zoom);
+            obj.edges = ExternalObjectConverter.toExtElementsArray(edges, 
zoom);
+            obj.mergedEdges = 
ExternalObjectConverter.toExtElementsArray(mergedEdges, zoom);
             
             return obj;
         }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/GraphUtils.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/GraphUtils.as     
2011-09-23 20:31:57 UTC (rev 26956)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/GraphUtils.as     
2011-09-23 21:26:36 UTC (rev 26957)
@@ -80,20 +80,20 @@
             return b;
         }
         
-        public static function getBounds(data:Data, 
+        public static function getBounds(nodes:*, edges:*, 
                                          ignoreNodeLabels:Boolean,
                                          ignoreEdgeLabels:Boolean):Rectangle {
-
             var bounds:Rectangle = new Rectangle();
             
-            if (data != null && data.nodes.length > 0) {
-                var minX:Number = Number.POSITIVE_INFINITY, minY:Number = 
Number.POSITIVE_INFINITY;
-                var maxX:Number = Number.NEGATIVE_INFINITY, maxY:Number = 
Number.NEGATIVE_INFINITY;
-                var lbl:TextSprite;
-                var fld:TextField;
-    
+            const PAD:Number = 2;
+            var minX:Number = Number.POSITIVE_INFINITY, minY:Number = 
Number.POSITIVE_INFINITY;
+            var maxX:Number = Number.NEGATIVE_INFINITY, maxY:Number = 
Number.NEGATIVE_INFINITY;
+            var lbl:TextSprite;
+            var fld:TextField;
+
+            if (nodes != null && nodes.length > 0) {
                 // First, consider the NODES bounds:
-                $each(data.nodes, function(i:uint, n:NodeSprite):void {
+                $each(nodes, function(i:uint, n:NodeSprite):void {
                     if (!isFilteredOut(n)) {
                         // The node size (its shape must have the same height 
and width; e.g. a circle)
                         var w:Number = n.width;
@@ -118,9 +118,11 @@
                         }
                     }
                 });
-                
+            }
+            
+            if (edges != null && edges.length > 0) {
                 // Also mesure edge bounds:
-                $each(data.edges, function(i:uint, e:EdgeSprite):void {
+                $each(edges, function(i:uint, e:EdgeSprite):void {
                     if (!isFilteredOut(e)) {
                         // Edge LABELS first, to avoid checking edges that are 
already inside the bounds:
                         lbl = e.props.label;
@@ -173,14 +175,18 @@
                         }
                     }
                 });
-                
-                const PAD:Number = 2;
-                bounds.x = minX - PAD;
-                bounds.y = minY - PAD;
-                bounds.width = maxX - bounds.x + PAD;
-                bounds.height = maxY - bounds.y + PAD;
             }
             
+            if (minX === Number.POSITIVE_INFINITY) minX = 0;
+            if (minY === Number.POSITIVE_INFINITY) minY = 0;
+            if (maxX === Number.NEGATIVE_INFINITY) maxX = 0;
+            if (maxY === Number.NEGATIVE_INFINITY) maxY = 0;
+            
+            bounds.x = minX - PAD;
+            bounds.y = minY - PAD;
+            bounds.width = maxX - bounds.x + PAD;
+            bounds.height = maxY - bounds.y + PAD;
+            
             return bounds;
         }
         
@@ -197,7 +203,8 @@
            
             for each (data in dataList) {
                 // The real subgraph bounds:
-                var b:Rectangle = getBounds(data, ignoreNodeLabels, 
ignoreEdgeLabels);
+                var b:Rectangle = getBounds(data.nodes, data.edges,
+                                            ignoreNodeLabels, 
ignoreEdgeLabels);
                 boundsList.push(b);
 
                 // Just to get the correct subgraph later:

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ContextMenuMediator.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ContextMenuMediator.as
    2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ContextMenuMediator.as
    2011-09-23 21:26:36 UTC (rev 26957)
@@ -151,7 +151,7 @@
                 menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,
                     function(evt:ContextMenuEvent):void {
                         var target:* = _rolledOverNode ? _rolledOverNode : 
_rolledOverEdge;
-                        target = ExternalObjectConverter.toExtElement(target);
+                        target = ExternalObjectConverter.toExtElement(target, 
graphProxy.zoom);
                         
                         var body:Object = { functionName: 
ExternalFunctions.INVOKE_CONTEXT_MENU_CALLBACK, 
                                             argument: { type: "contextmenu",

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as   
    2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as   
    2011-09-23 21:26:36 UTC (rev 26957)
@@ -282,7 +282,7 @@
                 
                 if (nodes != null && nodes.length > 0) {
                     var fn:FirstNeighborsVO  = new FirstNeighborsVO(nodes, 
ignoreFilteredOut);
-                    obj = fn.toObject();
+                    obj = fn.toObject(graphProxy.zoom);
                     obj = JSON.encode(obj);
                 }
             }
@@ -291,39 +291,44 @@
         }
 
         private function getNodeById(id:String):String {
-            var obj:Object = 
ExternalObjectConverter.toExtElement(graphProxy.getNode(id));
+            var obj:Object = 
ExternalObjectConverter.toExtElement(graphProxy.getNode(id),
+                                                                  
graphProxy.zoom);
             return JSON.encode(obj);
         }
         
         private function getEdgeById(id:String):String {
-            var obj:Object = 
ExternalObjectConverter.toExtElement(graphProxy.getEdge(id));
+            var obj:Object = 
ExternalObjectConverter.toExtElement(graphProxy.getEdge(id),
+                                                                  
graphProxy.zoom);
             return JSON.encode(obj);
         }
         
         private function getNodes():String {
-            var arr:Array = 
ExternalObjectConverter.toExtElementsArray(graphProxy.graphData.nodes);
+            var arr:Array = 
ExternalObjectConverter.toExtElementsArray(graphProxy.graphData.nodes,
+                                                                       
graphProxy.zoom);
             return JSON.encode(arr);
         }
         
         private function getEdges():String {
             var edges:Array = graphProxy.edges;
-            var arr:Array = ExternalObjectConverter.toExtElementsArray(edges);
+            var arr:Array = ExternalObjectConverter.toExtElementsArray(edges, 
graphProxy.zoom);
             return JSON.encode(arr);
         }
         
         private function getMergedEdges():String {
             var edges:Array = graphProxy.mergedEdges;
-            var arr:Array = ExternalObjectConverter.toExtElementsArray(edges);
+            var arr:Array = ExternalObjectConverter.toExtElementsArray(edges, 
graphProxy.zoom);
             return JSON.encode(arr);
         }
         
         private function getSelectedNodes():String {
-            var arr:Array = 
ExternalObjectConverter.toExtElementsArray(graphProxy.selectedNodes);
+            var arr:Array = 
ExternalObjectConverter.toExtElementsArray(graphProxy.selectedNodes,
+                                                                       
graphProxy.zoom);
             return JSON.encode(arr);
         }
         
         private function getSelectedEdges():String {
-            var arr:Array = 
ExternalObjectConverter.toExtElementsArray(graphProxy.selectedEdges);
+            var arr:Array = 
ExternalObjectConverter.toExtElementsArray(graphProxy.selectedEdges,
+                                                                       
graphProxy.zoom);
             return JSON.encode(arr);
         }
         
@@ -406,7 +411,7 @@
                 
                 // Finally convert the items to a plain objects that can be 
returned:
                 for each (newElement in newAll) {
-                    o = ExternalObjectConverter.toExtElement(newElement);
+                    o = ExternalObjectConverter.toExtElement(newElement, 
graphProxy.zoom);
                     ret.push(o);
                 }
             } catch (err:Error) {
@@ -438,7 +443,7 @@
                 graphMediator.initialize(Groups.NODES, [n]);
                 
                 if (updateVisualMappers) 
sendNotification(ApplicationFacade.GRAPH_DATA_CHANGED);
-                o = ExternalObjectConverter.toExtElement(n);
+                o = ExternalObjectConverter.toExtElement(n, graphProxy.zoom);
 
             } catch (err:Error) {
                 trace("[ERROR]: addNode: " + err.getStackTrace());
@@ -458,7 +463,7 @@
                 graphMediator.initialize(Groups.EDGES, [e]);
                 
                 if (updateVisualMappers) 
sendNotification(ApplicationFacade.GRAPH_DATA_CHANGED);
-                o = ExternalObjectConverter.toExtElement(e);
+                o = ExternalObjectConverter.toExtElement(e, graphProxy.zoom);
                 
             } catch (err:Error) {
                 trace("[ERROR]: addEdge: " + err.getStackTrace());
@@ -493,7 +498,7 @@
                 sendNotification(ApplicationFacade.UPDATE_DATA, { group: 
group, items: items, data: data });
         }
         
-        private function getNetworkModel():Object {
+        private function getNetworkModel():String {
                var data:Object = graphProxy.graphData;
                var nodesSchema:DataSchema = graphProxy.nodesSchema;
                var edgesSchema:DataSchema = graphProxy.edgesSchema;
@@ -501,12 +506,15 @@
                var nodesTable:GraphicsDataTable = new 
GraphicsDataTable(data.nodes, nodesSchema);
             var edgesTable:GraphicsDataTable = new 
GraphicsDataTable(data.group(Groups.REGULAR_EDGES), edgesSchema);
             var ds:DataSet = new DataSet(nodesTable, edgesTable);
+            
+            var model:Object = ExternalObjectConverter.toExtNetworkModel(ds);
                
-            return ExternalObjectConverter.toExtNetworkModel(ds);
+            return JSON.encode(model);
         }
         
         private function getNetworkAsText(format:String="xgmml", 
options:Object=null):String {
-            return graphProxy.getDataAsText(format, options);
+            var viewCenter:Point = graphMediator.getViewCenter();
+            return graphProxy.getDataAsText(format, viewCenter, options);
         }
         
         private function getNetworkAsImage(format:String="pdf", 
options:Object=null):String {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/GraphMediator.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/GraphMediator.as  
2011-09-23 20:31:57 UTC (rev 26956)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/GraphMediator.as  
2011-09-23 21:26:36 UTC (rev 26957)
@@ -42,6 +42,7 @@
     import flash.events.KeyboardEvent;
     import flash.events.MouseEvent;
     import flash.events.TimerEvent;
+    import flash.geom.Point;
     import flash.ui.Keyboard;
     import flash.utils.Timer;
     
@@ -178,7 +179,8 @@
             graphView.draw(graphProxy.graphData,
                            configProxy.config,
                            configProxy.visualStyle, 
-                           graphProxy.zoom);
+                           graphProxy.zoom,
+                           graphProxy.viewCenter);
         }
         
         public function applyVisualStyle(style:VisualStyleVO):void {
@@ -331,6 +333,10 @@
             }
         }
         
+        public function getViewCenter():Point {
+            return graphView.viewCenter;
+        }
+        
         // ========[ PRIVATE METHODS 
]==============================================================
 
         private function onRenderInitialize(evt:GraphViewEvent):void {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphView.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphView.as
   2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphView.as
   2011-09-23 21:26:36 UTC (rev 26957)
@@ -68,6 +68,19 @@
         // ========[ PUBLIC PROPERTIES 
]============================================================
 
         public var vis:GraphVis;
+        
+        public function get viewCenter():Point {
+            var vc:Point = new Point(stage.stageWidth/2, stage.stageHeight/2); 
// canvas center
+            vc = vis.globalToLocal(vc); // in case vis is not positioned in 
(0,0)
+            
+            var b:Rectangle = vis.getRealBounds();
+            vc.x -= b.x;
+            vc.y -= b.y;
+            vc.x *= vis.scaleX;
+            vc.y *= vis.scaleX;
+            
+            return vc;
+        }
 
                // ========[ CONSTRUCTOR 
]==================================================================
 
@@ -81,7 +94,8 @@
                
                // ========[ PUBLIC METHODS 
]===============================================================
 
-        public function draw(data:Data, config:ConfigVO, style:VisualStyleVO, 
zoom:Number):void {
+        public function draw(data:Data, config:ConfigVO, style:VisualStyleVO,
+                             scale:Number, viewCenter:Point):void {
             this._config = config;
             this._style = style;
                hitArea = Sprite(parent);
@@ -90,8 +104,10 @@
             resize();
 
             createVisualization(data, config.currentLayout.name);
-            if (zoom != 1.0) zoomTo(zoom);
 
+            if (scale !== 1.0)
+                scale = zoomTo(scale);
+            
             // -----------------------------
             var par:Parallel = applyLayout(config.currentLayout);
             
@@ -99,6 +115,24 @@
                evt.currentTarget.removeEventListener(evt.type, 
arguments.callee);
                evt.currentTarget.dispose();
                 dispatchEvent(new 
GraphViewEvent(GraphViewEvent.RENDER_COMPLETE));
+                
+                // Set the view center:
+                if (viewCenter != null) {
+                    var cc:Point = new Point(stage.stageWidth/2, 
stage.stageHeight/2); // canvas center
+                    cc = vis.globalToLocal(cc); // in case vis is not 
positioned in (0,0)
+                    
+                    var vc:Point = vis.globalToLocal(viewCenter);
+                    
+                    // We cannot assume the graph was aligned at (0,0)!
+                    var gb:Rectangle = vis.getRealBounds();
+                    vc.x -= gb.x;
+                    vc.y -= gb.y;
+                    
+                    // Move the center of the viewport to the specified 
position (it actually moves vis)
+                    var dx:Number = (cc.x - vc.x)*scale;
+                    var dy:Number = (cc.y - vc.y)*scale;
+                    panGraph(dx, dy);
+                }
             });
             par.play();
         }
@@ -133,7 +167,7 @@
         * Zoom the "camera" until it reaches the required scale.
         * @return The actual scale value after the zooming is executed.
         */
-        public function zoomTo(scale:Number):void { trace("-> Zoom to: " + 
scale);
+        public function zoomTo(scale:Number):Number { trace("-> Zoom to: " + 
scale);
                        if (scale < _config.minZoom)
                 scale = _config.minZoom;
             else if (scale > _config.maxZoom)
@@ -141,6 +175,8 @@
                        
                        var delta:Number = scale / vis.scaleX;
                        zoomBy(delta);
+                       
+                       return scale;
         }
         
         public function zoomToFit():Number {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphVis.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphVis.as
    2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/components/GraphVis.as
    2011-09-23 21:26:36 UTC (rev 26957)
@@ -389,7 +389,10 @@
             });
             if (_config.edgeLabelsVisible) edgeLabeler.operate();
 
-            var bounds:Rectangle = GraphUtils.getBounds(d, 
!_config.nodeLabelsVisible, !_config.edgeLabelsVisible);
+            var bounds:Rectangle = GraphUtils.getBounds(d.nodes,
+                                                        d.edges,
+                                                        
!_config.nodeLabelsVisible,
+                                                        
!_config.edgeLabelsVisible);
             
             return bounds;
         }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/ExternalObjectConverterTest.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/ExternalObjectConverterTest.as
   2011-09-23 20:31:57 UTC (rev 26956)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/model/converters/ExternalObjectConverterTest.as
   2011-09-23 21:26:36 UTC (rev 26957)
@@ -267,11 +267,11 @@
             
             // NODES
             var props:Array = 
["data","shape","borderColor","borderWidth","opacity","visible","color",
-                               "x","y","size","width","height"/*, "degree", 
"indegree", "outdegree"*/];
+                               
"x","y","rawX","rawY","size","width","height"/*, "degree", "indegree", 
"outdegree"*/];
             var attrs:Array = ["id"];
             
             for each (var n:NodeSprite in data.nodes) {
-                o = ExternalObjectConverter.toExtElement(n);
+                o = ExternalObjectConverter.toExtElement(n, 1);
                 assertEquals(Groups.NODES, o.group);
                 
                 for each (k in props) assertTrue("Node property: " + k, 
o.hasOwnProperty(k));
@@ -286,7 +286,7 @@
             attrs = ["id","source","target","directed"];
             
             for each (var e:EdgeSprite in data.edges) {
-                o = ExternalObjectConverter.toExtElement(e);
+                o = ExternalObjectConverter.toExtElement(e, 1);
                 assertEquals(Groups.EDGES, o.group);
                 
                 for each (k in props) assertTrue("Edge property: " + k, 
o.hasOwnProperty(k));

-- 
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.

Reply via email to