Author: clopes
Date: 2011-07-29 13:10:21 -0700 (Fri, 29 Jul 2011)
New Revision: 26337

Modified:
   cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test1.graphml
   cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/SVGExporter.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/ErrorCodes.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/Labeler.as
Log:
Fixed #2498: PDF and SVG: Line breaks in labels (SVG only!)
Improved label alignment--automatic text justification for each horizontal 
anchor.
Updated JS tests.

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test1.graphml
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test1.graphml        
2011-07-29 20:04:37 UTC (rev 26336)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/fixtures/test1.graphml        
2011-07-29 20:10:21 UTC (rev 26337)
@@ -1,9 +1,10 @@
 <graphml>
+  <key id="label" for="all" attr.name="label" attr.type="string"/>
+
   <key id="weight" for="node" 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"/>
@@ -18,7 +19,7 @@
     <node id="1">
       <data key="weight">0.45</data>
       <data key="ranking">1</data>
-      <data key="label">n1</data>
+      <data key="label">n1&#xA;TEST LINE BREAK</data>
       <data key="type">1</data>
       <data key="shape">ELLIPSE</data>
       <data key="special">false</data>

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js   2011-07-29 
20:04:37 UTC (rev 26336)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js   2011-07-29 
20:10:21 UTC (rev 26337)
@@ -151,6 +151,12 @@
 function runGraphTests(moduleName, vis, options) {
        module(moduleName);
 
+       var _errId;
+    var _onError = function(evt) {
+       _errId = evt.value.id;
+    }
+    vis.addListener("error", _onError);
+       
        test("Initialization Parameters", function() {
         same(vis.panZoomControlVisible(), options.panZoomControlVisible, 
"Pan-zoom control visible?");
         same(vis.nodeLabelsVisible(),     options.nodeLabelsVisible,     "Node 
Labels visible?");
@@ -1037,13 +1043,12 @@
        var ids = [];
        
        // 1: Update all nodes and edges (same data):
-        var data = { weight: 1/*, new_attr: "ignore it!"*/ };
+        var data = { weight: 1 };
         vis.updateData(data);
        
         all = vis.nodes().concat(vis.edges());
         $.each(all, function(i, el) {
                same(el.data.weight, 1, "weight updated ("+el.data.id+")");
-//             same(el.data.new_attr, undefined, "New attribute ignored 
("+el.data.id+")");
        });
         
         // 2: Update more than one node and edge at once (by ID - ALL groups - 
same data):
@@ -1133,23 +1138,16 @@
         ok(vis.node(id).data.weight === null, "Node weight should be null");
         
         // Test Errors:
-        var errId;
-        var onError = function(evt) {
-               errId = evt.value.id;
-        }
-        vis.addListener("error", onError);
         
-        // 7: Update a field with type 'int' to null (should set 0 as default):
+        // 7: Update a field with type 'int' to null => ERROR:
         vis.updateData("nodes", [id], { ranking: null });
-        same(errId, "dat001", "node.data.ranking (error: int type with null 
value)");
-        errId = null;
+        same(_errId, "dat001", "node.data.ranking (error: int type with null 
value)");
+        _errId = null;
         
-        // 8: Update a field with type 'boolean' to null (should set false as 
default):
+        // 8: Update a field with type 'boolean' to null => ERROR:
         vis.updateData("nodes", [id], { special: null });
-        same(errId, "dat001", "node.data.special (error: boolean type with 
null value)");
-        errId = null;
-        
-        vis.removeListener("error", onError);
+        same(_errId, "dat001", "node.data.special (error: boolean type with 
null value)");
+        _errId = null;
     });
     
     test("Get Data Schema", function() {
@@ -1367,7 +1365,7 @@
        var base64 = vis.pdf();
        var beginning = 
"JVBERi0xLjUKMSAwIG9iago8PC9UeXBlIC9QYWdlcwovS2lkcyBbMyAwIFJdCi9Db3VudCAxPj4K";
 
-       ok(base64.length > 13000, "PDF string has compatible length 
("+base64.length+")");
+       ok(base64.length > 9000, "PDF string has compatible length 
("+base64.length+")");
        same(base64.indexOf(beginning), 0, "PDF begins with correct chars");
     });
     

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/SVGExporter.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/SVGExporter.as
        2011-07-29 20:04:37 UTC (rev 26336)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/model/converters/SVGExporter.as
        2011-07-29 20:10:21 UTC (rev 26337)
@@ -43,6 +43,7 @@
     import flash.geom.Point;
     import flash.geom.Rectangle;
     import flash.text.TextField;
+    import flash.text.TextFormatAlign;
     import flash.utils.ByteArray;
     
     import mx.graphics.codec.PNGEncoder;
@@ -368,14 +369,17 @@
                     var lblSize:int = Math.round(lbl.size*_scale);
                     
                     if (text == null || text === "" || lblSize < 1) continue;
+                    
                     var field:TextField = lbl.textField;
+                    var lines:Array = text.split("\r");
 
                     // ATTENTION!!!
                     // It seems that Flash does not convert points to pixels 
correctly. 
                     // See: - http://alarmingdevelopment.org/?p=66
                     //      - 
http://www.actionscript.org/forums/showthread.php3?p=821842
                     // I found out that the text height is usually 28% smaller 
than the label size.
-                    var textHeight:Number = lbl.size * 0.72;
+                    var textHeight:Number = lbl.size * 0.72 * _scale;
+                    textHeight *= 1.5; // vertical spacing between lines
                     var textWidth:Number = field.textWidth;
 
                     // Get the Global label point (relative to the stage):
@@ -390,23 +394,27 @@
 
                     var hpad:Number = 2;
                     switch (hAnchor) {
-                        case Anchors.LEFT:   p.x += hpad * _scale; break;
-                        case Anchors.CENTER: p.x -= (textWidth/2)*_scale; 
break;
-                        case Anchors.RIGHT:  p.x -= (textWidth + hpad)*_scale; 
break;
+                        case Anchors.LEFT:   p.x += (hpad * _scale); break;
+                        case Anchors.RIGHT:  p.x -= (hpad * _scale); break;
                     }
                     // Vertical anchor:
                     // The label height is different from the real text 
height, because
                     // there is a margin between the text and the text field 
border:
                     var vpad:Number = 2;
+                    
                     switch (vAnchor) {
-                        case Anchors.TOP:    p.y += (field.height - 
textHeight)/2 * _scale; break;
-                        case Anchors.MIDDLE: p.y -= textHeight/2 * _scale; 
break;
-                        case Anchors.BOTTOM: p.y -= (vpad + textHeight) * 
_scale; break;
+                        case Anchors.TOP:
+                            p.y -= textHeight/2;
+                            p.y += ( textHeight/4 + vpad );
+                            break;
+                        case Anchors.MIDDLE:
+                            p.y -= ( (textHeight/2) * lines.length );
+                            p.y -= textHeight/6;
+                            break;
+                        case Anchors.BOTTOM:
+                            p.y -= ( (textHeight * lines.length) + vpad );
+                            break;
                     }
-                    
-                    // Flare's label cordinates is relative to the label's 
upper-left corner (x,y)=(0,0),
-                    // but AlivePDF uses the bottom-left corner instead 
(x,y)=(0,fonSize):
-                    p.y += textHeight*_scale;
 
                     var style:String = lbl.italic ? 'italic': 'normal';
                     var weight:String = lbl.bold ? 'bold' : 'normal';
@@ -418,10 +426,22 @@
                     else if (family == Fonts.TYPEWRITER) family = 'courier';
                     
                     var c:String = Utils.rgbColorAsString(lbl.color);
-                    var a:Number = lbl.alpha;
+                    var a:Number = d.alpha;
+                    var ta:String = getTextAnchor(lbl);
+
+                    svg += '<text font-family="'+family+'" 
font-style="'+style+'" font-weight="'+weight+'" stroke="none" fill="'+c+'"' +
+                                ' fill-opacity="'+a+'" font-size="'+lblSize+'" 
x="'+p.x+'" y="'+p.y+'" style="text-anchor:'+ta+';">';
                     
-                    svg += '<text font-family="'+family+'" 
font-style="'+style+'" font-weight="'+weight+'" stroke="none" fill="'+c+'"' +
-                                ' fill-opacity="'+a+'" font-size="'+lblSize+'" 
x="'+p.x+'" y="'+p.y+'">' + text+ '</text>';
+                    if (lines.length > 0) {
+                        for (var i:int = 0; i < lines.length; i++) {
+                            var ln:String = lines[i];
+                            svg += '<tspan style="text-anchor:'+ta+';" 
x="'+p.x+'" dy="'+textHeight+'">'+ln+'</tspan>';
+                        }
+                    } else {
+                        svg += text;
+                    }
+                    
+                    svg += '</text>';
                 }
             }
             
@@ -610,5 +630,14 @@
      
             return pageEdge / graphEdge;
         }
+        
+        private function getTextAnchor(lbl:TextSprite):String {
+            var ta:String = 'middle';
+     
+            if (lbl.textFormat.align === TextFormatAlign.LEFT) ta = 'start';
+            else if (lbl.textFormat.align === TextFormatAlign.RIGHT) ta = 
'end';
+     
+            return ta;
+        }
     }
 }
\ No newline at end of file

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/ErrorCodes.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/ErrorCodes.as     
2011-07-29 20:04:37 UTC (rev 26336)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/util/ErrorCodes.as     
2011-07-29 20:10:21 UTC (rev 26337)
@@ -37,6 +37,7 @@
         // ========[ CONSTANTS 
]====================================================================
 
         public static const INVALID_DATA_CONVERSION:String = "dat001";
+        public static const MISSING_DATA_FIELD:String = "dat002";
         public static const BROKEN_IMAGE:String = "img001";
 
         // ========[ CONSTRUCTOR 
]==================================================================

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/Labeler.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/Labeler.as 
2011-07-29 20:04:37 UTC (rev 26336)
+++ cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/Labeler.as 
2011-07-29 20:10:21 UTC (rev 26337)
@@ -43,6 +43,7 @@
     import flash.events.Event;
     import flash.geom.Point;
     import flash.text.TextFormat;
+    import flash.text.TextFormatAlign;
     
     import org.cytoscapeweb.util.Utils;
     import org.cytoscapeweb.util.methods.$each;
@@ -138,8 +139,7 @@
                 label.text = getLabelText(d);
                 label.visible = visible;
 
-                updateTextFormat(d);
-                label.applyFormat(textFormat);
+                updateLabel(d, label);
                 _access.setValue(d, label);
                 
                 if (_policy == LAYER) {
@@ -158,18 +158,9 @@
                 }
             } else if (label && !cacheText) {
                 label.text = getLabelText(d);
-                
-                updateTextFormat(d);
-                label.applyFormat(textFormat);
+                updateLabel(d, label);
             }
             
-            label.textMode = textMode;
-            label.horizontalAnchor = horizontalAnchor;
-            label.verticalAnchor = verticalAnchor;           
-
-            if (hAnchor != null) label.horizontalAnchor = hAnchor(d);
-            if (vAnchor != null) label.verticalAnchor = vAnchor(d);
-            
             return label;
         }
 
@@ -226,12 +217,28 @@
             label.render();
         }
 
-        protected function updateTextFormat(d:DataSprite):void {
+        protected function updateLabel(d:DataSprite, label:TextSprite):void {
+            label.textMode = textMode;
+            label.horizontalAnchor = horizontalAnchor;
+            label.verticalAnchor = verticalAnchor;           
+
+            if (hAnchor != null) label.horizontalAnchor = hAnchor(d);
+            if (vAnchor != null) label.verticalAnchor = vAnchor(d);
+
             if (fontName != null) textFormat.font = fontName(d);
             if (fontColor != null) textFormat.color = fontColor(d);
             if (fontSize != null) textFormat.size = fontSize(d);
             if (fontWeight != null) textFormat.bold = (fontWeight(d) === 
"bold");
             if (fontStyle != null) textFormat.italic = (fontStyle(d) === 
"italic");
+            
+            if (label.horizontalAnchor === TextSprite.CENTER)
+                textFormat.align = TextFormatAlign.CENTER;
+            if (label.horizontalAnchor === TextSprite.RIGHT)
+                textFormat.align = TextFormatAlign.RIGHT;
+            if (label.horizontalAnchor === TextSprite.LEFT)
+                textFormat.align = TextFormatAlign.LEFT;
+                
+            label.applyFormat(textFormat);
         }
         
         // ========[ PRIVATE METHODS 
]==============================================================

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