Page 1 of 3 123 LastLast
Results 1 to 10 of 25

Thread: Simple BoxComponent which encapsulates a Raphael canvas

  1. #1
    Sencha User
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,890

    Default Simple BoxComponent which encapsulates a Raphael canvas

    The latest cross-browser graphics library: http://ajaxian.com/archives/raphael-...ur-graphics-on

    Simply use this BoxComponent subclass. It exports all the methods of a Raphael canvas, and will participate in a layout:

    Code:
    Ext.ux.Raphael = Ext.extend(Ext.BoxComponent, {
        onRender: function(ct) {
            var p = this.paper = Raphael(ct.dom), v;
            this.el = Ext.get(p.canvas);
    
    //      Export all methods from this paper object which will not override our native
    //      methods like setSize etc.
            for (var prop in p) {
                v = p[prop];
                if (!this[prop] && Object.prototype.hasOwnProperty.call(p, prop) && Ext.isFunction(v)) {
                    this[prop] = v.createDelegate(p);
                }
            }
    
    //      We always cache our size
            this.cacheSizes = true;
        },
    
        getWidth: function() {
            return this.lastSize.width;
        },
    
        getHeight: function() {
            return this.lastSize.height;
        },
    
        onResize: function(w, h) {
            this.paper.setSize(w, h);
        }
    });

  2. #2
    Sencha User
    Join Date
    Mar 2008
    Posts
    566

    Default

    Raphael is very nice. Does it depend on any other libraries like jquery?

    Are there any extjs raphael examples?

    Marty

  3. #3
    Sencha User
    Join Date
    Mar 2007
    Location
    Singapore
    Posts
    6,232

    Thumbs up

    neat


    hey @nige, what's the purpose of this?
    Code:
    Object.prototype.hasOwnProperty.call(p, prop)
    why not just
    Code:
    p.hasOwnProperty(prop)
    (scratched. see http://www.extjs.com/forum/showthrea...817#post384817)


    [edit]
    additionally, would it be more efficient to simply remove p.create before commencing, then re-add it when we're done instead of performing the check once per iteration?
    Code:
    Ext.ux.Raphael = Ext.extend(Ext.BoxComponent, {
        onRender: function(ct) {
            var p = this.paper = Raphael(ct.dom),
                create = p.create,
                prop, v;
    
            this.el = Ext.get(p.canvas);
    
            // Export all methods from this paper object which will
            // not override our native methods like setSize etc.
            delete p.create;
            for (prop in p) {
                v = p[prop];
    
                if (!this[prop] && Object.prototype.hasOwnProperty.call(p, prop) && Ext.isFunction(v)) {
                    this[prop] = v.createDelegate(p);
                }
            }
            p.create = create;
        },
    
        onResize: function(w, h) {
            this.el.dom.setAttribute('width', w);
            this.el.dom.setAttribute('height', h);
        }
    });
    (disclaimer: i've not taken a look at the source for Raphael yet, but i'm assuming there are tons of methods in there.)
    Last edited by mystix; 9 Sep 2009 at 9:44 AM. Reason: edit

  4. #4
    Sencha User
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,890

    Default

    The returned object is an augmented DOM object. I found problems calling hasOwnProperty directly on it using the normal member notation, so I used the methods directly from the Object prorotype.

    Good idea about knocking create out before copying the methods up into the Ext Component.

  5. #5
    Sencha User
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,890

    Default

    Quote Originally Posted by moegal View Post
    Raphael is very nice. Does it depend on any other libraries like jquery?

    Are there any extjs raphael examples?

    Marty

    If you can find any Raphael examples anwhere, then just use the code on the instance of Ext.ux.Raphael.

  6. #6
    Sencha User
    Join Date
    Mar 2007
    Location
    Singapore
    Posts
    6,232

    Default

    Quote Originally Posted by Animal View Post
    The returned object is an augmented DOM object. I found problems calling hasOwnProperty directly on it using the normal member notation, so I used the methods directly from the Object prorotype.

    Good idea about knocking create out before copying the methods up into the Ext Component.
    i see. updated the code block above to match.
    thanks for the info

  7. #7
    Sencha User
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,890

    Default

    Here's an example which will drop into examples/anywhere.

    The actual graphics drawing code is culled directly from http://dev.opera.com/articles/view/r...t-api-for-svg/ which shows that the Ext Raphael object simply exports all Raphael's functionality while conforming to Ext's requirements for a BoxComponent so that it will participate in Ext layouts.

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <title>Raphel</title>
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../../ext-all-debug.js"></script>
    <script type="text/javascript" src="raphael.js"></script>
    <script type="text/javascript">
    Ext.ux.Raphael = Ext.extend(Ext.BoxComponent, {
        onRender: function(ct) {
            var p = this.paper = Raphael(ct.dom), v;
            this.el = Ext.get(p.canvas);
    
    //      Export all methods from this paper object which will not override our native
    //      methods like setSize etc.
            for (var prop in p) {
                v = p[prop];
                if (!this[prop] && Object.prototype.hasOwnProperty.call(p, prop) && Ext.isFunction(v)) {
                    this[prop] = v.createDelegate(p);
                }
            }
    
    //      We always cache our size
            this.cacheSizes = true;
        },
    
        getWidth: function() {
            return this.lastSize.width;
        },
    
        getHeight: function() {
            return this.lastSize.height;
        },
    
        onResize: function(w, h) {
            this.paper.setSize(w, h);
        }
    });
    Ext.reg('raphael', Ext.ux.Raphael);
    
    Ext.onReady(function() {
        var r = new Ext.ux.Raphael(),
            sectorsCount = 12,
            color = "#000",
            width = 15,
            r1 = 35,
            r2 = 60,
            cx = 200,
            cy = 200,
            sectors = [],
            opacity = [],
            beta = 2 * Math.PI / sectorsCount,
            pathParams = {stroke: color, "stroke-width": width, "stroke-linecap": "round"};
    
        new Ext.Window({
            x: 20, y: 20,
            title: 'Raphael Test',
            height: 432,
            width: 414,
            layout: 'fit',
            items: r
        }).show();
    
    //  Keep spinner in centre
        r.on('resize', function () {
            var ncx = r.getWidth() / 2;
            var ncy = r.getHeight() / 2;
            for (var i = 0; i < sectorsCount; i++) {
                sectors[i].translate(ncx - cx, ncy - cy);
            }
            cx = ncx;
            cy = ncy;
        });
    
        for (var i = 0; i < sectorsCount; i++) {
            var alpha = beta * i - Math.PI / 2,
            cos = Math.cos(alpha),
            sin = Math.sin(alpha);
            opacity[i] = 1 / sectorsCount * i;
            sectors[i] = r.path(pathParams)//.attr("stroke", Raphael.getColor())
            .moveTo(cx + r1 * cos, cy + r1 * sin)
            .lineTo(cx + r2 * cos, cy + r2 * sin);
        }
    
        (function ticker() {
            opacity.unshift(opacity.pop());
            for (var i = 0; i < sectorsCount; i++) {
                sectors[i].attr("opacity", opacity[i]);
            }
            r.safari();
            setTimeout(ticker, 1000 / sectorsCount);
        })();
    
        function createChart(paper, cx, cy, r, values, labels, stroke) {
            var rad = Math.PI / 180;
    	    function sector(cx, cy, r, startAngle, endAngle, params) {
    	        var x1 = cx + r * Math.cos(-startAngle * rad),
    	            x2 = cx + r * Math.cos(-endAngle * rad),
    	            y1 = cy + r * Math.sin(-startAngle * rad),
    	            y2 = cy + r * Math.sin(-endAngle * rad);
    	        return paper.path(params, ["M", cx, cy, " L", x1, y1, " A", r, r, 0, +(endAngle - startAngle > 180), 0, x2, y2, "z"]);
    	    }
    	    var angle = 0,
    	        total = 0,
    	        start = 0,
    	        process = function (j) {
    	            var value = values[j],
    	                angleplus = 360 * value / total,
    	                popangle = angle + (angleplus / 2),
    	                color = "hsb(" + start + ", 1, .5)",
    	                ms = 500,
    	                delta = 30,
    	                bcolor = "hsb(" + start + ", 1, 1)",
    	                p = sector(cx, cy, r, angle, angle + angleplus, {gradient: "90-" + bcolor + "-" + color, stroke: stroke, "stroke-width": 3}),
    	                txt = paper.text(cx + (r + delta + 35) * Math.cos(-popangle * rad), cy + (r + delta) * Math.sin(-popangle * rad), labels[j]).attr({fill: bcolor, stroke: "none", opacity: 0, "font-family": 'Fontin-Sans, Arial', "font-size": "20px"});
    	            p.mouseover(function () {
    	                p.animate({scale: [1.1, 1.1, cx, cy]}, ms, "elastic");
    	                txt.animate({opacity: 1}, ms, "elastic");
    	            }).mouseout(function () {
    	                p.animate({scale: [1, 1, cx, cy]}, ms, "elastic");
    	                txt.animate({opacity: 0}, ms);
    	            });
    	            angle += angleplus;
    	            start += .1;
    	        };
    	    for (var i = 0, ii = values.length; i < ii; i++) {
    	        total += values[i];
    	    }
    	    for (var i = 0; i < ii; i++) {
    	        process(i);
    	    }
    	};
    
        var chart = new Ext.ux.Raphael(),
            values = [],
            labels = [];
        Ext.getBody().select("tr").each(function (r) {
            values.push(Ext.DomQuery.selectNumber("td", r.dom));
            labels.push(Ext.DomQuery.selectValue("th", r.dom));
        });
        new Ext.Window({
            title: 'Pie Chart',
            height: 500,
            width: 500,
            layout: 'fit',
            items: chart 
        }).show();
        var w = chart.getWidth();
        var h = chart.getHeight();
        var rad = (Math.min(w, h) - 200) / 2
        createChart(chart, w/2, h/2, rad, values, labels, "#fff"); 
    
    });
    </script>
    </head>
    <body>
      <table style="display:none">
          <tr>
              <th>Ruby</th>
              <td>40%</td>
          </tr>
          <tr>
              <th>JavaScript</th>
              <td>26%</td>
          </tr>
          <tr>
              <th>Shell</th>
              <td>5%</td>
          </tr>
          <tr>
              <th>Python</th>
              <td>5%</td>
          </tr>
          <tr>
              <th>PHP</th>
              <td>4%</td>
          </tr>
          <tr>
              <th>C</th>
              <td>4%</td>
          </tr>
          <tr>
              <th>Perl</th>
              <td>3%</td>
          </tr>
          <tr>
              <th>C++</th>
              <td>2%</td>
          </tr>
          <tr>
              <th>Java</th>
              <td>2%</td>
          </tr>
          <tr>
              <th>Objective-C</th>
              <td>2%</td>
          </tr>
      </table>
    </body>
    </html>

  8. #8
    Sencha User
    Join Date
    Mar 2008
    Posts
    566

    Default

    thanks!that is easy.

    Marty

  9. #9

    Question

    I tried to execute the last example but it did not work.
    Anyway,
    I was wondering if it is possible to use the rect function from raphael with this boxcomponent?

    PHP Code:
    // regular rectangle
    var paper.rect(10105050); 
    but how do I do that?

    I tried something like:
    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <title>Raphel</title>
    <link rel="stylesheet" type="text/css" href="ext-3.0.0/resources/css/ext-all.css" />
    <script type="text/javascript" src="ext-3.0.0/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="ext-3.0.0/ext-all-debug.js"></script>
    <script type="text/javascript" src="raphael.js"></script>
    <script type="text/javascript">
    
    Ext.ux.Raphael = Ext.extend(Ext.BoxComponent, {
        onRender: function(ct) {
            var p = this.paper = Raphael(ct.dom),
                create = p.create,
                prop, v;
    
            this.el = Ext.get(p.canvas);
    
            // Export all methods from this paper object which will
            // not override our native methods like setSize etc.
            delete p.create;
            for (prop in p) {
                v = p[prop];
    
                if (!this[prop] && Object.prototype.hasOwnProperty.call(p, prop) && Ext.isFunction(v)) {
                    this[prop] = v.createDelegate(p);
                }
            }
            p.create = create;
        },
    
        onResize: function(w, h) {
            this.el.dom.setAttribute('width', w);
            this.el.dom.setAttribute('height', h);
        }
    });
    Ext.reg('raphael', Ext.ux.Raphael);
    
    Ext.onReady(function() {
    
        var rect_test = new Ext.ux.Raphael(),
            rect(10, 10, 50, 50);     
    
        new Ext.Window({
            x: 20, y: 20,
            title: 'Raphael Test',
            height: 432,
            width: 414,
            layout: 'fit',
            items: rect_test
        }).show();
      });
    </script>
    </head>
    <body>
    
    </body>
    </html>
    But it does not work, any hints?

  10. #10
    Sencha User
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,890

    Default

    The browser doesn't give you any hints then?

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •