Page 1 of 4 123 ... LastLast
Results 1 to 10 of 31

Thread: Ext.ux.chart (non-flash version,pure js)

  1. #1
    Ext User
    Join Date
    Apr 2008
    Location
    hangzhou,china
    Posts
    26

    Default Ext.ux.chart (non-flash version,pure js)

    hi ~my friends
    i'd like to share my extension,
    there was a Ext.chart already available,but it goes along with the adobe flash.my solution is totally pure javascript(thanks to google iecanvas).so ~if you don't want use flash in application,you can use my extension instead.
    wish you have interesting with it.
    below is the constructor code:
    Code:
    Ext.ns("Ext.ux.chart");
    
    /**
     * @class Ext.ux.chart ??????
     * @author cdj
     * @version beta1.4.4
     */
    
    Ext.ux.chart = Ext.extend(Ext.Component, {
        /**
         * @cfg ?????
         */
        width:300,
        /**
         * @cfg ?????
         */
        height:160,
        /**
         * @cfg ?????????????
         */
        offsets:'5,40,5,5',
        /**
         * @cfg ??css?
         */
        baseCls:'ux-chart',
        /**
         * @cfg ?????
         */
        borderWidth:1,
        /**
         * @cfg store
         */
        store:{},
        initComponent:function(){
            Ext.ux.chart.superclass.initComponent.call(this);
            this.addEvents(
                //supported event list here
            );
            this.ds = this.store;
        },
        
        onRender:function(ct,pos){
            this.preCreateSkeleton();
            this.createSkeleton(ct,pos);
            this.createXHandler();//behavior
            
            this.romCVX.init();
            this.ramCVX.init();
            this.ds.on('load',this.onLoad,this);
        },
        
        /**
         * ????????????????
         */
        preCreateSkeleton:function(){
            var _off = this.offsets.split(',');
            Ext.applyIf(this,{
                nOffset:Ext.isGecko?new Number(_off[0])+1:new Number(_off[0]),//?????????
                eOffset:new Number(_off[1]),
                sOffset:new Number(_off[2]),
                wOffset:Ext.isGecko?new Number(_off[3])+7:new Number(_off[3])
            });
            this.chartHeight = this.height + this.sOffset + this.nOffset;//??
            this.chartWidth = this.width + this.wOffset + this.eOffset;
    
        },
        
        /**
         * ???????????,???????????
         * @param ct ?????????
         * @param pos 
        */
        createSkeleton:function(ct,pos){
            var ramLayerId = Ext.id("","ui2-chart-ram-cvs-");
            var romLayerId = Ext.id("","ui2-chart-rom-cvs-");
            var labelLayerId = Ext.id("","ui2-chart-label-");//???
            var evLayerId = Ext.id("","ui2-chart-ev-");//???
            var tl = "position:absolute;left:0px;top:0px;";
            this.style += "position:relative;";
            var tpl = new Ext.XTemplate(
                '<div>',
                '<canvas id ='+romLayerId+' width = "'+this.chartWidth+'" height = "'+this.chartHeight+'" style='+tl+'background:'+this.bgColor+'></canvas>',//things that wouldn't be changed
                '<div id = "'+labelLayerId+'" style = "position:absolute;left:0px;top:0px;"></div>',//?????
                '<canvas id ='+ramLayerId+' width = "'+this.chartWidth+'" height = "'+this.chartHeight+'" style='+tl+'></canvas>',//things that would be changed in run-time
                '<div id = "'+evLayerId+'" style = "position:absolute;left:0px;top:0px;"></div>',//?????
                '</div>'
            );
            this.el = tpl.append(ct,"",true);
            if(this.baseCls){
                this.el.addClass(this.baseCls);
            }
            if(this.cls){
                this.el.addClass(this.cls);
            }
            if(this.id){
                this.el.dom.id = this.el.id = this.id;
            }
            this.evct = Ext.get(evLayerId);
            var ramCV = this.el.child("#"+ramLayerId,true);
            this.lbct = Ext.get(labelLayerId);
            var romCV = this.el.child("#"+romLayerId,true);
            if(Ext.isIE){
                ramCV = Ext.get(window.G_vmlCanvasManager.initElement(ramCV)).dom;
                romCV = Ext.get(window.G_vmlCanvasManager.initElement(romCV)).dom;
            }
            this.ramCVX = ramCV.getContext('2d');
            this.romCVX = romCV.getContext('2d');
            
        },
        
        /**
         * rom?????? override it
         */
        romLayerInitial:Ext.emptyFn,
        
        /**
         * ram?????? override it
         */
        ramLayerInitial:Ext.emptyFn,
        
        /**
         * ram????? override it
         */
        draw:Ext.emptyFn,
        
        /**
         * ram????? override it
         */
        redraw:Ext.emptyFn,
        
        createXHandler:function(){
            Ext.applyIf(this,{
                gridBgColor:this.colors.gridbg,
                gridColor:this.colors.grid,
                frameColor:this.colors.frame,
                lineColor:this.colors.line
            });
            
            this.romCVX.init = this.romLayerInitial.createDelegate(this.romCVX,[this]);
            delete this.romLayerInitial;
            
            Ext.apply(this.ramCVX,{
                init :this.ramLayerInitial.createDelegate(this.ramCVX,[this]),
                draw :this.draw.createDelegate(this.ramCVX,[this]),
                redraw:this.redraw.createDelegate(this.ramCVX,[this])
            });
            
            delete this.romLayerInitial;
            delete this.draw;
            delete this.redraw;
        },
        
        addLabel:function(conf){
            var lbf = {};
            Ext.apply(lbf,conf,{
                id:Ext.id('','ui2-monitor-label-'),
                position:[0,0],
                tag:'span'
            });
            if(typeof lbf.style != "undefined"){
                lbf.style += ";font-size:12px;white-space:nowrap";
            }else {
                lbf.style = "font-size:12px;white-space:nowrap";
            }
            if(typeof lbf.p == "undefined"){
                lbf.p = lbf.position;
            }
            //?????font-family?????????ie???????
            lbf.style += (";font-family:tahoma,arial,helvetica,sans-serif;position:absolute;left:"+lbf.p[0]+"px;top:"+lbf.p[1]+"px");
            delete lbf.p;
            delete lbf.position;
            if(lbf.vmode){
                lbf.style += ';writing-mode:tb-rl;';
                delete lbf.vmode;
            }
            
            if(typeof lbf.background != "undefined"){
                lbf.style += (";background:"+lbf.background);
            }
            var label = this.lbct.createChild(lbf,'',false);
            return label;
        },
        getStore:function(){
            return this.store;  
        },
        /**
         * override it
         */
        onLoad:Ext.emptyFn
    })
    
    /**
     * ??????
     * @author cdj
     * @usage:
     *    var histogram = new Ext.ux.chart.Histogram({
            //renderTo:cdjel,
            width:300,
            height:200,
            colSize:20,
            gapSize:0.9,
            _coloffset:30,
            offsets:'10,0,80,10',
            valueField:'value',
            nameField:'name',
            store:new Ext.data.SimpleStore({
                fields:["name","value"],
                autoLoad:true,
                url:'res.json'
            }),
            colors:{
                gridbg:'rgb(241,233,196)',
                grid:'rgb(196,196,196)',
                frame:'rgb(0,0,0)',
                line:'rgb(0,0,0)'
            }, 
            yAxis:[{
                text:'10K',
                value:10*1024
            },{
                text:'1K',
                value:1*1024
            },{
                text:'500bytes',
                value:500
            },{
                text:'100bytes',
                value:100
            },{
                text:'10bytes',
                value:10
            }]
        });
    */
    Ext.ux.chart.Histogram = Ext.extend(Ext.ux.chart, {
        xfontSize:12,
        gapScale:0.2,
        colsLeftOffset:20,//????
        xTickTpl:"",
        /**
         * @cfg ??
         */
        colors:{
            gridbg:'rgb(241,233,196)',
            grid:'rgb(196,196,196)',
            frame:'rgb(0,0,0)',
            line:'rgb(0,0,0)'
        },
        
        /**
         * rom??????
         */
        romLayerInitial:function(chart){
            chart.xScale = (chart.width - 2*chart.borderWidth)/chart.xAxisN;
            chart.yScale = (chart.height - 2*chart.borderWidth)/chart.yAxis.length;
            this.save();
            this.translate(chart.wOffset,chart.nOffset);
            this.fillStyle = chart.gridBgColor;
            this.fillRect(0,0,chart.width,chart.height);
            this.fill();
            this.strokeStyle = chart.frameColor;
            this.moveTo(0,0);
            this.lineTo(0,chart.height);
            this.lineTo(chart.width,chart.height);
            this.lineTo(chart.width,0);
            this.lineTo(0,0);
            this.stroke();
            // draw the grid and ticks
            
            this.strokeWidth = chart.borderWidth;//add by cj
            
            this.strokeStyle = chart.gridColor;
            var _p = [];// position for label
            var _s;// scale for each tick
            for(var i = 0;i < chart.yAxis.length;i++){
                _s = i*chart.yScale;
                this.moveTo(0,_s);
                this.lineTo(chart.width+5,_s);// this '5' is the small line for tick
                _p[0] = chart.chartWidth - chart.eOffset + 6; // this '4' is just for adjust the tick's position
                _p[1] = _s +3;
                chart.addLabel({
                    position:_p,
                    //vmode:true,
                    html:chart.yAxis[i].text
                })
            }
            this.stroke();
            //eof draw
        },
        ramLayerInitial:function(chart){
            this.save();
            this.translate(chart.wOffset,chart.nOffset);
            this.lineStyle = chart.lineColor;
        },
        /**
         * @override ??onload
         */
        onLoad:function(){
            this.doDataConvert();
            this.ramCVX.clearRect(0,0,10000,10000);
            if(this.evct.first()){
                var id = this.evct.id;
                Ext.destroy(this.evct);//reconstruct evct layer
                this.evct = Ext.DomHelper.append(this.el,{
                    id:id
                },true);
            }else {
                //do nothing
            }
            this.ramCVX.draw();
            Ext.ux.chart.Histogram.superclass.onLoad.call(this);
        },
        /**
         * @private ????
         * ?????column modal??????????????
         * ????????store??????????????????????
         * ???????????????????????draw???store??????
         */
        doDataConvert:function(){
            this.pd = {};//???????,data for paint 
            var sow = (this.width-this.colsLeftOffset)/this.ds.getCount();//self owned width
            
            //calculate gapWidth
            var gw = sow*this.gapScale;
            
            //calculate every ColumnWidth
            var cw = sow - gw;
            var cols = [];
            for(var i=0,cm = this.columnModal;i<cm.length;i++){
                //Ext.log(cm[i].width)
                var _tpl = new Ext.XTemplate(cm[i].tipTpl||"{"+cm[i].dataIndex+"}");
                _tpl.compile();
                var c = {
                    width:cm[i].width*cw,
                    tipTpl:_tpl,
                    dataIndex:cm[i].dataIndex,
                    color:cm[i].color || "#000"
                    //,color:"rgba()"
                };
                cols.push(c);
            }
            var _xpl = new Ext.XTemplate(this.xTickTpl);
            _xpl.compile();
            Ext.apply(this.pd,{
                gapWidth:gw,
                xTpl:_xpl,
                selfOwnedWidth:sow,
                columnsWidth:cw,
                colCfgs:cols
            })
        },
        /**
         * @override ???????
         */
        draw:function(chart){
            var pd = chart.pd;
            var cf = pd.colCfgs;
            this.beginPath();
            this.save();
            this.translate(chart.colsLeftOffset+chart.borderWidth,chart.borderWidth);
            var parseColor = Ext.ux.chart.ColorManager.parseColor.createDelegate(Ext.ux.chart.ColorManager);
            chart.ds.each(function(r,i){
                var _off = 0;//??????????
                for(var ii = 0;ii<cf.length;ii++){
                    
                    var _x = i*pd.selfOwnedWidth+_off;
                    var _y = chart.getYPixelByValue(r.get(cf[ii].dataIndex));
                    var _w = cf[ii].width;
                    var _h = chart.height-2*chart.borderWidth-_y;
                    var _clor = parseColor(cf[ii].color);
                    //begin render column
                    var gradient = this.createLinearGradient(_x,_y,_x+_w,_y);
                    gradient.addColorStop(0, _clor.s);
                    gradient.addColorStop(1, _clor.e);
                    this.fillStyle = gradient;
                    this.fillRect(_x,_y,_w,_h);
                    this.fill();
                    
                      //???
                    var m = parseInt(cf[ii].width*0.5);
                    var gradient2 = this.createLinearGradient(_x+m,_y,_x+_w,_y);
                    gradient2.addColorStop(0, 'rgba(235,245,235,0.2)');
                    gradient2.addColorStop(1, 'rgba(235,245,235,0.6)');
                    this.fillStyle = gradient2;
                    this.fillRect(_x+m,_y,_w-m,_h);
                    this.fill();
                    //eof render column
                    
                    //add tip
                    var _ev = chart.addBlankImage({
                        p:[chart.wOffset+chart.colsLeftOffset+_x,_y+chart.nOffset],
                        height:_h,
                        width:_w,
                        background:''
                    });
                    new Ext.ToolTip({
                        target: _ev,
                        title: cf[ii].title || pd.xTpl.apply(r.data),
                        width:200,
                        html: cf[ii].tipTpl.apply(r.data),
                        trackMouse:true
                    });
                    //eof add tip
                    
                    _off += _w;
                }//eof pd cols
                
                var tx= i*pd.selfOwnedWidth+0.5*pd.columnsWidth;
                //TODO ???
                if(Ext.isGecko){
                    this.save();
                    this.fillStyle = chart.lineColor;
                    this.translate(tx-parseInt(chart.xfontSize/6),chart.height+5);
                    this.rotate(90 * Math.PI / 180);
                    this.mozTextStyle = chart.xfontSize+"px simsun";
                    this.mozDrawText(pd.xTpl.apply(r.data));
                    this.restore();
                }else {
                    //ie
                    chart.addLabel({
                        html:pd.xTpl.apply(r.data),
                        p:[chart.colsLeftOffset + tx-parseInt(chart.xfontSize/6)+chart.wOffset,chart.height+chart.nOffset+5],
                        vmode:true
                    })
                }
            },this);
            this.closePath();
            this.stroke();
            this.restore();
        },
        /**
         * ??????
         */
        reconstruct:function(config){
            Ext.apply(this,config);
            //clear up rom and ram layer
            //this.ramCVX.restore();
            this.ramCVX.restore();
            //this.ramCVX.restore();
            this.ramCVX.clearRect(0,0,10000,10000);
            
            if(this.evct.first()){
                var id = this.evct.id;
                Ext.destroy(this.evct);//reconstruct evct layer
                this.evct = Ext.DomHelper.append(this.el,{
                    id:id
                },true);
            }else {
                //do nothing
            }
            this.romCVX.restore();
            this.romCVX.clearRect(0,0,10000,10000);
            
            if(this.lbct.first()){
                var id = this.lbct.id;
                Ext.destroy(this.lbct);//reconstruct evct layer
                this.lbct = Ext.DomHelper.append(this.el,{
                    id:id
                },true);
            }else {
                //do nothing
            }
            this.romCVX.init();
            this.ramCVX.init();
    
            
        },
        /**
         * ????
         */
        redraw:function(){
            this.ramCVX.clearRect(0,0,10000,10000);
            if(this.evct.first()){
                var id = this.evct.id;
                Ext.destroy(this.evct);//reconstruct evct layer
                this.evct = Ext.DomHelper.append(this.el,{
                    id:id
                },true);
            }else {
                //do nothing
            }
            this.ramCVX.draw();
        },
        /**
         * @private
         * @describe addBlankImage
         */
        addBlankImage:function(conf){
            var lbf = {};
            Ext.apply(lbf,conf,{
                position:[0,0],
                src:Ext.BLANK_IMAGE_URL,
                tag:'img',
                width:10,
                height:10
            });
            if(lbf.style){
                lbf.style += ';font-size:12px;white-space:nowrap';
            }else {
                lbf.style = 'font-size:12px;white-space:nowrap';
            }
            if(!lbf.p){
                lbf.p = lbf.position;
            }
            lbf.style += (";position:absolute;left:"+lbf.p[0]+"px;top:"+lbf.p[1]+"px;height:"+lbf.height+"px;width:"+lbf.width);
            delete lbf.p;
            delete lbf.position;
            if(lbf.vmode){
                lbf.style += ';writing-mode:tb-rl';
                delete lbf.vmode;
            }
            if(lbf.background){
                lbf.style += (";background:"+lbf.background);
            }
            var label = this.evct.createChild(lbf,'',false);
            return label;
        },
        /**
         * @private
         * @describe ??Y??????????????????
         * @returns Y???
        */
        getYPixelByValue:function(v){
            var max,min;
            for(var i = 0;i < this.yAxis.length;i++){
                if(v >= this.yAxis[i].value){
                    max = i==0?v:this.yAxis[i-1].value;
                    min = this.yAxis[i].value;
                    break;
                }else {
                    continue;
                }
            }
            var i = i-1;
            if(typeof min == 'undefined'){
                min = 0;
                max = this.yAxis[i].value;
            }
            var result;
            if(max == min){
                result = 0;
            }else{
                result = (1-(v - min)/(max - min) + i)*this.yScale;
            }
            return result;
        }
    });
    
    Ext.ux.chart.ColorManager = {
        parseColor: function(str){
            
            var result;
    
            // rgb(num,num,num)
            if((result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str)))
                return this.getColor(parseInt(result[1]), parseInt(result[2]), parseInt(result[3]));
        
            // rgba(num,num,num,num)
            if((result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)))
                return this.getColor(parseInt(result[1]), parseInt(result[2]), parseInt(result[3]), parseFloat(result[4]));
                
            // rgb(num%,num%,num%)
            if((result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str)))
                return this.getColor(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55);
        
            // rgba(num%,num%,num%,num)
            if((result = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)))
                return this.getColor(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55, parseFloat(result[4]));
                
            // #a0b1c2
            if((result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str)))
                return this.getColor(parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16));
        
            // #fff
            if((result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str)))
                return this.getColor(parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16));
    
            // Otherwise, we're most likely dealing with a named color.
            var name = str.trim().toLowerCase();
            if(name == 'transparent'){
                return this.getColor(255, 255, 255, 0);
            }
            return ((result = this.colors[name])) ? this.getColor(result[0], result[1], result[2]) : false;
        },
        getColor: function(r, g, b, a){
            this.rgba = ['r','g','b','a'];
            var x = 4;
            while(-1<--x){
                this[this.rgba[x]] = arguments[x] || ((x==3) ? 1.0 : 0);
            }
            return this.normalize();
        },
        normalize: function(){
            var limit = this.limit;
            this.r = limit(parseInt(this.r), 0, 255);
            this.g = limit(parseInt(this.g), 0, 255);
            this.b = limit(parseInt(this.b), 0, 255);
            this.a = limit(this.a, 0, 1);
            return {s:"rgba("+this.r+","+this.g+","+this.b+","+this.a+")",e:"rgba("+this.r+","+this.g+","+this.b+","+(this.a-0.5)+")"};
            //return "rgba("+this.r+","+this.g+","+this.b+","+this.a+")";
        },
        limit: function(val,minVal,maxVal){
            return Math.max(Math.min(val, maxVal), minVal);
        },
        colors : {
            aqua:[0,255,255],
            azure:[240,255,255],
            beige:[245,245,220],
            black:[0,0,0],
            blue:[0,0,255],
            brown:[165,42,42],
            cyan:[0,255,255],
            darkblue:[0,0,139],
            darkcyan:[0,139,139],
            darkgrey:[169,169,169],
            darkgreen:[0,100,0],
            darkkhaki:[189,183,107],
            darkmagenta:[139,0,139],
            darkolivegreen:[85,107,47],
            darkorange:[255,140,0],
            darkorchid:[153,50,204],
            darkred:[139,0,0],
            darksalmon:[233,150,122],
            darkviolet:[148,0,211],
            fuchsia:[255,0,255],
            gold:[255,215,0],
            green:[0,128,0],
            indigo:[75,0,130],
            khaki:[240,230,140],
            lightblue:[173,216,230],
            lightcyan:[224,255,255],
            lightgreen:[144,238,144],
            lightgrey:[211,211,211],
            lightpink:[255,182,193],
            lightyellow:[255,255,224],
            lime:[0,255,0],
            magenta:[255,0,255],
            maroon:[128,0,0],
            navy:[0,0,128],
            olive:[128,128,0],
            orange:[255,165,0],
            pink:[255,192,203],
            purple:[128,0,128],
            violet:[128,0,128],
            red:[255,0,0],
            silver:[192,192,192],
            white:[255,255,255],
            yellow:[255,255,0]
        }
    };
    Ext.reg('ux-chart-histogram', Ext.ux.chart.Histogram);
    and below is the usage example:

    Code:
    Ext.BLANK_IMAGE_URL = 'lib/ext/resources/images/default/s.gif';
    
    Ext.onReady(function(){
        //????
        //new a chart
        var histogram = new Ext.ux.chart.Histogram({
            width:700,
            height:300,
            //renderTo:cdjel,
            offsets:'10,40,80,10',
            store:new Ext.data.SimpleStore({
                fields:["name","value1","value2"],
                autoLoad:true,
                url:'res.json'
            }),
            xTickTpl:"2009 ?{name}",
            columnModal:[{
                dataIndex:'value1',
                width:0.5,
                tipTpl:"??????{value1}",
                color:'olive'
                //color:"rgba(0,0,0,1)"
                },{
                dataIndex:'value2',
                //tipTpl:"??????{value1}",
                //color:'purple',
                width:0.2
                },{
                dataIndex:'value2',
                width:0.3,
                tipTpl:"??????{value2}",
                color:'navy'
            }],
            colors:{
                gridbg:'rgb(241,233,196)',
                grid:'rgb(196,196,196)',
                frame:'rgb(0,0,0)',
                line:'rgb(0,0,0)'
            }, 
            yAxis:[{
                text:'10K',
                value:10*1024
                },{
                text:'1K',
                value:1*1024
                },{
                text:'500bytes',
                value:500
                },{
                text:'100bytes',
                value:100
                },{
                text:'10bytes',
                value:10
            }],
            listeners:{
                render:function(){
                    //Ext.log("my chart rendered");
                }
            }
        });
        
        
        var win = new Ext.Window({
            width:800,
            height:460,
            title:'????',
            items:[histogram]
        })
        win.show();
       
    })
    
    in this example,your data from the server should looked like this :
    
    Code:
    [
        ['??','1020','100'],
        ['??','300','500'],
        ['??','500','200'],
        ['??','200','400'],
        ['??','200','700'],
        ['??','300','100'],
        ['??','500','600'],
        ['??','1000','100']
    ]
    there is a screenshot and a demo in the attachment.

    to run this demo,you just need to take four steps.
    1.download it.
    2.decompress all files to the web application deployment folder(suppose you named"app").
    your folder structure under the "app" should be :
    /lib/mylib/excanvas.js
    /lib/mylib/UI2.chart.Histogram.js
    histogram.js
    histogram.html
    3.mkdir /lib/ext ,and copy the ext lib files to it
    /lib/ext/resources/* (css and image files)
    /lib/ext/ext-base.js
    /lib/ext/ext-all.js
    4.launch your server --> view the histogram.html.

    you can modify my code as you wish, and use the modified code in your products.
    notice that :
    you must include the "google iecanvas" (which named excanvas.js) in your page,otherwise it won't work.
    you can download it from my attachment or http://excanvas.sourceforge.net/
    Code:
    <!--[if IE]><script type="text/javascript" src="lib/mylib/excanvas.js"></script><![endif]-->
    .its size is just 27k.

    I'd appreciate comments and/or suggestions.

    sorry for my broken english,i couldn't express my thinking very well,hope you could understand what i wrote
    Attached Images Attached Images
    Attached Files Attached Files

  2. #2
    Ext User
    Join Date
    Apr 2008
    Location
    hangzhou,china
    Posts
    26

    Default

    ???????????

  3. #3
    Ext User
    Join Date
    Jun 2009
    Location
    guangzhou China
    Posts
    2

    Thumbs up

    ???????????????????
    ?????????.../

  4. #4
    Ext User
    Join Date
    Apr 2008
    Location
    hangzhou,china
    Posts
    26

    Default

    ?? ?????

  5. #5

    Default

    ????????? !!
    ??

  6. #6
    Sencha User
    Join Date
    Oct 2009
    Posts
    6

    Thumbs up

    ????

    ?? Flash ????

  7. #7
    Sencha Premium Member
    Join Date
    Jun 2008
    Posts
    381

    Default

    Nice, looks alot like Ext Flot !
    I`m from Holland!

  8. #8
    Sencha User
    Join Date
    Apr 2009
    Location
    / .de / ST / HAL
    Posts
    33

    Exclamation

    Why the conversation is not in english??? Many people can read english posts, but smal count of people can understand chinese.

    ==============

    ?????????????????????????????????????
    Best regards

    Matthias

    _______________
    ExtJS is the best ajax-framework, that I know!

  9. #9

    Default

    ??????

  10. #10
    Ext User
    Join Date
    Apr 2008
    Location
    hangzhou,china
    Posts
    26

    Default

    Quote Originally Posted by lxfliu View Post
    ????

    ?? Flash ????
    ??

Page 1 of 4 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
  •