求EXT2.0 画图解放方案

求EXT2.0 画图解放方案

问题描述:

求EXT2.0 图画解放方案
就是像柱状,饼状,线等等的
EXT2.0的,能用的,谢谢了

//pieChart.js
Ext.ns('Ext.ux');
Ext.ux.pieChart = Ext.extend(Ext.BoxComponent, {
circleX : 0,
circleY : 0,
data : undefined,
labels : [],
labelX : 0,
labelY : 0,
radius : 100,
onRender : function(ct, position) {
Ext.ux.pieChart.superclass.onRender.call(this, ct, position);
this.ct = Ext.get(ct);

this.createCanvas(ct);
},
createCanvas : function(ct) {
//if (!this.el) {

var canvas = document.createElement("canvas");
this.ct.dom.appendChild(canvas);
this.el = Ext.get(canvas);
if (Ext.isIE && G_vmlCanvasManager)
this.el = Ext.get(G_vmlCanvasManager.initElement(canvas));
//}
this.el = Ext.get(this.el);
this.setCanvasSize(this.width, this.height);
this.canvas = Ext.getDom(this.el);
this.el.position('absolute', this.zIndex);
this.ctx = this.getContext();
},
drawCircle : function(ctx) {
//if(ctx){var m=5};
//alert(m);
this.shadow ? this.makeShadow() : '';
var total = 0;
for (var i = 0; i < this.data.length; i++)
total += this.data[i][1];
this.startangle = -Math.PI / 2;
ctx.lineWidth = 2;
ctx.strokeStyle = "black";
for (var i = 0; i < this.data.length; i++) {
var d = this.data[i];
this.endangle = this.startangle + d[1] / total * Math.PI * 2;
ctx.beginPath();
ctx.moveTo(this.circleX, this.circleY);
ctx.arc(this.circleX, this.circleY, this.radius,
this.startangle, this.endangle, false);
ctx.closePath();
ctx.fillStyle = d[2];
ctx.fill();
ctx.stroke();
this.startangle = this.endangle;

        ctx.fillStyle = d[2];
        ctx.fillRect(this.labelX, this.labelY + 30 * i, 20, 20);
        ctx.strokeRect(this.labelX, this.labelY + 30 * i, 20, 20);
        var label = Ext.get(this.ct).createChild();
        label.position('absolute');
        label.setLeftTop(this.labelX + 30, this.labelY + 30 * i - 4);
        label.dom.innerHTML = this.labels[i] || d[0];
        alert("xx");
    }
    //this.shadow ? this.makeShadow() : '';
},
makeShadow : function() {
    var c = {
        x : this.circleX,
        y : this.circleY,
        r : this.radius
    }
    //this.ctx.beginPath();
    this.ctx.arc(c.x + 5, c.y + 5, c.r, 0, Math.PI * 2, false)
    this.ctx.closePath();
    var radgrad = this.ctx.createRadialGradient(c.x + 5, c.y + 5, 0, c.x
            + 5, c.y + 5, c.r);
    radgrad.addColorStop(0, '#555555');
    this.ctx.fillStyle ='#555555';
    this.ctx.fill();
},
getContext : function() {
    return this.el.dom.getContext("2d");
},

afterRender : function() {
    Ext.ux.pieChart.superclass.afterRender.apply(this, arguments);
    var context = this.ctx;
    this.drawCircle(context);
    // this.drawLabel(context);
},
setCanvasSize : function(w, h) {
    this.el.setSize(w, h);
    this.el.set( {
        width : w,
        height : h
    });
}

});
Ext.onReady(function() {
var pie = new Ext.ux.pieChart( {
width : 600,
height : 400,
shadow : true,
data : [['North', 12, 'red'], ['South', 23, 'blue'],
['East', 34, 'yellow'], ['West', 45, 'green']],
circleX : 200,
circleY : 200,
labelX : 400,
labelY : 100,
radius : 150
});
pie.render('xx');
});

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


Tween
<script type="text/javascript" src="excanvas.js"></script>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css"/>
<script type="text/javascript"  src="extjs/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="extjs/ext-all-debug.js"></script>           
    <script type="text/javascript" src="extjs/ext-lang-zh_CN.js"></script>  
<script type="text/javascript" src="javascript/BaseChart.js"></script>  
    <script type="text/javascript" src="javascript/BalloonTip.js"></script> 
<script type="text/javascript" src="javascript/Zline.js"></script>  

<br> /*修正check-group,radio-group*/<br> .x-form-check-wrap,.x-form-radio-wrap{<br> padding:3px 0 0 0;<br> line-height:15px;width:100px;<br> }<br> .x-form-check-group .x-form-check-wrap,.x-form-radio-group .x-form-radio-wrap{<br> height:15px;<br> }<br> .ext-ie .x-form-check-group .x-form-check-wrap,.ext-ie .x-form-radio-group .x-form-radio-wrap{<br> height:17px;<br> }<br><br>


ext2没有这个 ext4才有。

可以试试ext2和fusioncharts结合做图片展示 比较快捷
可以看看这个
[url]http://hi.baidu.com/390873374/blog/item/7ecad43394f09e5aad4b5f8f.html[/url]

可以取我看见 看看 fusionchart 与Ext组合

//baseChart.js//折线图
Ext.ns('Ext.chart');
Ext.chart.BaseChart = Ext.extend(Ext.BoxComponent, {
width:500,
heigth:285,
onRender : function(ct, position) {
Ext.chart.BaseChart.superclass.onRender.call(this, ct, position);
this.ct = Ext.get(ct);
this.ct.position();
this.ct.setStyle('overflow', 'hidden');
this.createCanvas();
},
createCanvas : function(ct) {
//if (!this.el) {
var canvas = document.createElement("canvas");
this.ct.dom.appendChild(canvas);
this.el = Ext.get(canvas);
if (Ext.isIE && G_vmlCanvasManager)
this.el = Ext.get(G_vmlCanvasManager.initElement(canvas));
// }
this.el = Ext.get(this.el);
this.setCanvasSize(this.width, this.height);
this.canvas = Ext.getDom(this.el);
this.el.position('absolute', this.zIndex);
this.ctx = this.getContext();
},
getContext : function() {
return this.el.dom.getContext("2d");
},

setCanvasSize : function(w, h) {
    this.el.setSize(w, h);
    this.el.set( {
        width : w,
        height : h
    });
}

});

balloonTip.js

Ext.ns('Ext.ux');
Ext.ux.BalloonTip = Ext.extend(Ext.BoxComponent, {
nodeWidth : 80,
nodeHeight : 40,
useCurveLine : true,
useCurveRate : 0.15,

yDetal : 0,
xDetal : 0,

xDetalRate : 40,
bWHDetalRate : 20,
xDetalBase : 10,
btWidth : 10,
btHeight : 10,
tWidth : 15,
tHeight : 15,
radius : 5,
rate : 1 / 2,
midRate : 1 / 2,
padRate : 1 / 10,

angleDetal : 0,
angleDetalStart : 0,

textCls : '',
data : [],
color : '',
direction : 't',
constrain : true,
autoRender : true,

onRender : function(ct, position) {
    Ext.ux.BalloonTip.superclass.onRender.call(this, ct, position);
    this.initDirection = this.direction;
    this.ct = ct;
    if (this.text)
        this.addText(this.text);
    this.createCanvas();
},
getZIndex : function() {
    return parseInt(this.ct.getStyle("z-index"), 10) || 11000;
},
show : function(text, xy) {
    Ext.ux.BalloonTip.superclass.show.apply(this, arguments);

    if (text && text.isXType && text.isXType('panel')) {
        if (!text.rendered)
            text.renderTo(this.ct);
        else
            text.show();
        this.textEl = text;
    } else {
        this.addText(text);
    }
    this.adjustOuter(xy[0], xy[1]);
    this.draw();
    this.setXY(xy);
},
hide : function(text) {
    this.direction = this.initDirection;
    Ext.ux.BalloonTip.superclass.hide.apply(this, arguments);
    if (this.textEl) {
        this.textEl.dom.innerHTML = "";
        this.textEl.setLeftTop(-10000, -10000);
        this.el.setLeftTop(-10000, -10000);
    }
},
createCanvas : function() {
    //if (!this.el) {
        var canvas = document.createElement("canvas");
        this.ct.dom.appendChild(canvas);
        this.el = Ext.get(canvas);
        if (Ext.isIE && G_vmlCanvasManager)
            this.el = Ext.get(G_vmlCanvasManager.initElement(canvas));
    //}
    this.el = Ext.get(this.el);
    this.setCanvasSize(this.width, this.height);
    this.canvas = Ext.getDom(this.el);
    this.el.position('absolute', this.zIndex || this.getZIndex() + 2);
    this.ctx = this.getContext();
},
getContext : function() {
    return this.el.dom.getContext("2d");
},
constrainXY : function(x1, y1) {
    if (this.constrain) {
        var constrainEl = Ext.get(this.constrainCt || document);
        var cbox = constrainEl.getBox(), tbox = this.el.getBox();
        var ox = tbox.x - cbox.x, oy = tbox.y - cbox.y;
        var or = tbox.right - cbox.right, ob = tbox.bottom - cbox.bottom;
        var ow = tbox.width - cbox.width, oh = tbox.height - cbox.height;
        switch (this.direction) {
            case 't' :
                ox < 0 ? x1 = x1 - ox : "";
                or > 0 ? x1 = x1 - or : "";
                if (oh < 0) {
                    oy < 0 ? y1 = y1 - oy : '';
                    ob > 0 ? this.changeDirection('b', x1, y1) : '';
                }
                break;
            case 'b' :
                ox < 0 ? x1 = x1 - ox : "";
                or > 0 ? x1 = x1 - or : "";
                if (oh < 0) {
                    ob > 0 ? y1 = y1 - ob : "";
                    oy < 0 ? this.changeDirection('t', x1, y1) : '';
                }
                break;
            case 'l' :
                ob > 0 ? y1 = y1 - ob : "";
                oy < 0 ? y1 = y1 - oy : "";
                if (ow < 0) {
                    ox < 0 ? x1 = x1 - ox : "";
                    or > 0 ? this.changeDirection('r', x1, y1) : '';
                }
                break;
            case 'r' :
                ob > 0 ? y1 = y1 - ob : "";
                oy < 0 ? y1 = y1 - oy : "";
                if (ow < 0) {
                    or > 0 ? x1 = x1 - or : "";
                    ox < 0 ? this.changeDirection('l', x1, y1) : '';
                }
                break;
        }
        x1 = parseInt(x1), y1 = parseInt(y1);
        x1 < 0 ? x1 = 0 : "";
        y1 < 0 ? y1 = 0 : "";
        //alert(x1,y1);
        this.setPagePosition(x1, y1);
    }
},
changeDirection : function(direction, x, y) {
    this.direction = direction;
    this.adjustOuter(x, y);
    this.draw();
},
addText : function(text) {
    if (!this.textEl) {
        this.textEl = Ext.get(this.ct).createChild();
        this.textEl.addClass(this.textCls);
    }
    Ext.DomHelper.overwrite(this.textEl, text);

    var size = Ext.util.TextMetrics.measure(this.textEl, text);
    this.nodeWidth = size.width + 10;
    this.nodeHeight = size.height + 10;
    this.textEl.setSize(this.nodeWidth, this.nodeHeight);
    this.textEl.position('absolute', this.zIndexText || this.getZIndex()
            + 3);
},
afterRender : function() {
    Ext.ux.BalloonTip.superclass.afterRender.apply(this, arguments);
},
setXY : function(xy) {
    this.setPagePosition(xy[0], xy[1]);
    this.constrainXY(xy[0], xy[1]);

},
setCanvasSize : function(w, h) {
    var width, height;
    switch (this.direction) {
        case 't' :
        case 'b' :
            width = this.nodeWidth + this.angleDetal || 0;
            height = this.nodeHeight + this.tHeight + this.yDetal;
            break;
        case 'l' :
        case 'r' :
            width = this.nodeWidth + this.tHeight + this.yDetal + 1;
            height = this.nodeHeight + this.angleDetal || 0;
            break;
    }
    this.el.setSize(width, height);
    this.el.set( {
        width : width,
        height : height
    });
    this.width = width;
    this.height = height;
},
between : function(x, min, max) {
    if (x < min)
        x = min;
    if (x > max)
        x = max;
    return x;
},
adjustStart : function() {
    var x = this.tWidth + this.yDetal, y = this.tHeight + this.yDetal;
    switch (this.direction) {
        case 't' :
            x = 0 + this.angleDetalStart || 0;
            break;
        case 'b' :
            x = 0 + this.angleDetalStart || 0, y = 0;
            break;
        case 'l' :
            x = y;
            y = 0 + this.angleDetalStart || 0;
            break;
        case 'r' :
            x = y;
            y = 0;
            break;
    }
    return {
        x : x,
        y : y
    };
},
calDetal : function() {
    var midRate = (this.rate - 0.5), absMidRate = Math.abs(midRate);
    var bWHDetal = absMidRate * this.bWHDetalRate;
    this.xDetal = midRate * this.xDetalRate;
    this.tWidth = this.btWidth + bWHDetal;
    this.tHeight = this.btHeight + bWHDetal;
    if (this.angleToCurve == false)
        this.useCurveLine = false;
    else
        this.useCurveLine = absMidRate < this.useCurveRate ? false : true;

},
calAngleDetal : function(w) {
    var o = this.radius + this.offsetLen + this.tWidth * this.midRate
            + this.xDetal;
    nwh = (w == 'w') ? this.nodeWidth : this.nodeHeight;
    if (o < 0) {
        this.angleDetal = Math.abs(o);
        this.angleDetalStart = Math.abs(o);
    } else if (o - nwh > 0)
        this.angleDetal = o - nwh;
    else {
        this.angleDetal = 0;
        this.angleDetalStart = 0;
    }
},
offset : function(wh, r, rate) {
    return (wh - 2 * r) * rate;
},
calOffsetLen : function(w) {
    var nwh = (w == "w") ? this.nodeWidth : this.nodeHeight;
    var len = (nwh - 2 * this.radius) * this.rate;
    var minLen = nwh * this.padRate;
    var maxLen = nwh - 2 * this.radius - this.tWidth - minLen;
    this.offsetLen = this.between(len, minLen, maxLen);
},
calRate : function(x, y, w) {
    if (this.constrainCt) {
        var ctBox = Ext.get(this.constrainCt).getBox();
        var v = (w == "w") ? (x - ctBox.x) / ctBox.width : (y - ctBox.y)
                / ctBox.height;
        this.rate = this.between(v, 0, 1);
    }
},
adjustOuter : function(x, y) {
    if (this.constrain) {
        switch (this.direction) {
            case 't' :
            case 'b' :
                var flag = 'w';
                break;
            case 'l' :
            case 'r' :
                var flag = 'h';
        }
        this.calRate(x, y, flag);
        this.calDetal();
        this.calOffsetLen(flag);
        this.calAngleDetal(flag);
    }
},
draw : function() {
    this.setCanvasSize();
    var len = this.offsetLen || 0, r = this.radius;
    var tw = this.tWidth, th = this.tHeight, nw = this.nodeWidth, nh = this.nodeHeight;
    var xy = this.adjustStart(), x = xy.x, y = xy.y;

    this.ctx.strokeStyle = this.bdcolor || '#000000';
    this.ctx.lineWidth = this.lineWidth || 1;
    this.ctx.fillStyle = this.bgcolor || 'white';
    this.ctx.clearRect(0, 0, this.width, this.height);
    this.ctx.beginPath();
    this.ctx.moveTo(x, y + r);
    this.ctx.quadraticCurveTo(x, y, x + r, y);

    this.drawAngle('t', len, x, y, r, tw, th);
    this.ctx.lineTo(x + nw - 2 * r, y);
    this.ctx.quadraticCurveTo(x + nw, y, x + nw, y + r);
    this.drawAngle('r', len, x, y, r, tw, th);

    this.ctx.lineTo(x + nw, y + nh - 2 * r);
    this.ctx.quadraticCurveTo(x + nw, y + nh, x + nw - r, y + nh);
    this.drawAngle('b', len, x, y, r, tw, th);

    this.ctx.lineTo(x + r, y + nh);
    this.ctx.quadraticCurveTo(x, y + nh, x, y + nh - r);
    this.drawAngle('l', len, x, y, r, tw, th);

    this.ctx.lineTo(x, y + r);
    this.ctx.fill();
    this.ctx.stroke();
},

onDestroy : function() {
    if (this.textEl)
        this.textEl.remove();
},
drawAngle : function(direction, len, x, y, r, tw, th) {
    var x1, y1, x2, y2, x3, y3, x4, y4, x5, y5;
    if (this.direction != direction)
        return;
    switch (this.direction) {
        case 't' :
            x1 = x + r + len, y1 = y;
            x2 = x1 + tw * this.midRate + this.xDetal;
            y2 = y1 - th - this.yDetal;
            x3 = x1 + tw, y3 = y1;
            break;
        case 'b' :
            x3 = x + r + len, y3 = y + this.nodeHeight;
            x1 = x3 + tw, y1 = y3;
            x2 = x3 + tw * this.midRate + this.xDetal;
            y2 = y3 + th + this.yDetal;
            break;
        case 'l' :
            x3 = x, y3 = y + r + len;
            x1 = x3, y1 = y3 + tw;
            x2 = x3 - th - this.yDetal;
            y2 = y3 + tw * this.midRate + this.xDetal;
            break;
        case 'r' :
            x1 = x + this.nodeWidth, y1 = y + r + len;
            x2 = x1 + th + this.yDetal;
            y2 = y1 + tw * this.midRate + this.xDetal;
            x3 = x1, y3 = y1 + tw;
    }

    this.ctx.lineTo(x1, y1);
    if (this.useCurveLine) {
        x4 = x1, y4 = y2;
        x5 = x3, y5 = y2;
        this.ctx.quadraticCurveTo(x4, y4, x2, y2);
        this.ctx.quadraticCurveTo(x5, y5, x3, y3);
    } else {
        this.ctx.lineTo(x2, y2);
        this.ctx.lineTo(x3, y3);
    }
},

realignText : function() {
    var xy = this.adjustStart(), x = xy.x, y = xy.y;
    x = this.x1 + x, y = this.y1 + y;
    this.textEl.setLeftTop(x, y);
},
setPagePosition : function(x2, y2) {
    Ext.ux.BalloonTip.superclass.setPagePosition.apply(this, arguments);
    this.realignText();
},
adjustPosition : function(x1, y1) {
    var detal = this.radius + this.offsetLen + this.tWidth * this.midRate
            + this.xDetal + this.angleDetalStart;
    switch (this.direction) {
        case 't' :
            x = x1 - detal;
            y = y1;
            break;
        case 'b' :
            x = x1 - detal;
            y = y1 - this.height;
            break;
        case 'l' :
            x = x1;
            y = y1 - detal;
            break;
        case 'r' :
            x = x1 - this.width;
            y = y1 - detal;
    }
    this.x1 = x;
    this.y1 = y;

    return {
        x : x,
        y : y
    };
}

});

// 背景色与背景图
// 采用panel,window做为内容
// 计算约束

Zline.js//折线图

Ext.ns('Ext.chart');
Ext.chart.Line = Ext.extend(Ext.chart.BaseChart, {
yMin : null,
yMax : null,
xColumns : 12,
yRows : 10,
series : [],
xLabels : [],
xTextOffset : 5,
yTextOffset : 10,
legendOffset : 5,
arrowHeight : 10,
arrowWidth : 10,
defaultLineWidth : 2,
repeat : 10,
timeCount : 0,
legend : true,
initComponent : function() {
Ext.chart.Line.superclass.initComponent.apply(this, arguments);
var str = '

'
+ ''
+ ' '
+ ' '
+ '
{year}年{name}销售额
全年平均销售额: {avg}万元
当前月销售额: {now}万元
';
if (!this.msgTpl) {
var t = new Ext.XTemplate(str);
t.compile();
Ext.chart.Line.prototype.msgTpl = t;
}
this.tipHide = true;
if (this.ds) {
for (var i = 0; i < this.ds.getCount(); i++) {
if (this.ds.getAt(i).data['state'] == 1)
return this.setData(i);
break;
}
}
},
onRender : function() {
Ext.chart.Line.superclass.onRender.apply(this, arguments);
this.dotDetail = new Ext.ux.BalloonTip( {
direction : 't',
yDetal : 3,
xDetal:15,
//useCurveRate : 0,
xDetalRate:60,
bWHDetalRate : 15,
constrainCt : this.ct
});
this.draw();
},
drawAxis : function() {
    this.drawXYAxis();
    this.drawXText();
    this.drawYText();

},
createVLabel : function(v, w, items) {
    var item = this.yText.createChild( {
        tag : 'span'
    });
    item.position('absolute');
    item.dom.appendChild(document.createTextNode(parseInt(v)));
    items.push([v, item]);
    item.getWidth() > w ? w = item.getWidth() : '';
    return [w, item.getHeight()];
},

drawYText : function() {
    if (this.yText)
        this.yText.remove();
    var step = this.yRange / (this.yRows - 1);
    this.yText = this.ct.createChild( {
        style : 'position:absolute;'
    });
    var w = 0, items = [];
    for (var n = 0, v = this.yMax; (v > this.yMin) && (n < this.yRows - 1); v -= step, n++)
        w = this.createVLabel(v, w, items)[0];
    var wh = this.createVLabel(this.yMin, w, items);
    this.yText.setWidth(wh[0]);
    this.yText.setLeftTop(this.cBox.l - wh[0] - this.yTextOffset, 0);/* 标值左边与y轴距离 */
    var rate = this.cBox.h / this.yRange, yoffset = (this.yMin * rate);
    for (i = 0; i < items.length; i++) {
        var item = items[i][1], pos = items[i][0];
        pos = this.cBox.h - pos * rate + yoffset;/* 标值位置在y轴高度上的体现 */
        item.setRight(0);
        item.setTop(parseInt(this.cBox.y + pos - wh[1] / 2) || 0);/* 定位为标值文本高度的* */
    }
},
drawXText : function() {
    if (this.xText)
        this.xText.remove();
    var step = this.cBox.w / (this.xColumns - 1);
    this.xText = this.ct.createChild();
    this.xText.position('absolute');
    this.xText.setWidth(this.width);
    this.xText.setLeftTop(0, this.cBox.b + this.xTextOffset);
    for (var i = 0; i < this.xColumns; i++) {
        var label = this.xText.createChild();
        label.dom.appendChild(document.createTextNode(this.xLabels[i]));
        label.position('absolute');
        var x = this.cBox.x + (step * i) - (label.getWidth() / 2);
        var h = label.getHeight();
        label.setLeftTop(x, 0);
    }
    this.xText.setHeight(h);
},
drawXYAxis : function() {
    var x = this.cBox.l, y = this.cBox.b;
    var x1 = this.cBox.x, y1 = this.cBox.y - this.arrowHeight;
    var x2 = this.cBox.r + this.arrowHeight, y2 = this.cBox.b;
    this.ctx.lineWidth = 1;
    this.ctx.strokeStyle = "black";
    this.ctx.beginPath();
    this.ctx.moveTo(x, y);
    this.ctx.lineTo(x1, y1);
    this.ctx.stroke();

    this.ctx.beginPath();
    this.ctx.moveTo(x1 - this.arrowWidth / 2, y1 + this.arrowHeight);
    this.ctx.lineTo(x1, y1);
    this.ctx.lineTo(x1 + this.arrowWidth / 2, y1 + this.arrowHeight);
    this.ctx.stroke();

    this.ctx.beginPath();
    this.ctx.moveTo(x, y);
    this.ctx.lineTo(x2, y2);
    this.ctx.stroke();

    this.ctx.beginPath();
    this.ctx.moveTo(x2 - this.arrowHeight, y2 - this.arrowWidth / 2);
    this.ctx.lineTo(x2, y2);
    this.ctx.lineTo(x2 - this.arrowHeight, y2 + this.arrowWidth / 2);
    this.ctx.stroke();
},
drawBackground : function() {
    var w = this.cBox.w, h = this.cBox.h, x = this.cBox.x, y = this.cBox.y;
    xgd = (this.xColumns) ? w / (this.xColumns - 1) : 0;
    ygd = (this.yRows) ? h / (this.yRows - 1) : 0;
    this.ctx.fillStyle = 'silver';
    if (xgd)
        for (i = xgd; i <= w; i += xgd)
            this.ctx.fillRect(x + i, y, 1, h - 1);
    if (ygd)
    for (i = h - ygd; i >= 0; i -= ygd)
            this.ctx.fillRect(x + 1, y + i, w, 1);
},
addLine : function(label, color, values, width, id, product) {
    this.series.push(this.initLine( {
        label : label,
        color : color,
        values : values,
        width : width || this.defaultLineWidth,
        id : id,
        product : product
    }));
},
initLine : function(line) {
    var sum = 0, len = line.values.length;
    for (var i = 0; i < len; i++)
        sum = sum + line.values[i];
    line.avgValue = sum / len;
    if (!line.tempValues)
        line.tempValues = [];
    for (var j = 0; j < len; j++)
        line.tempValues[j] = line.avgValue;
    return line;
},
drawAnimLines : function() {
    this.timeCount++;
    if (this.timeCount == 1)
        this.beforeAnimal();
    var last = (this.timeCount === this.repeat);
    if (!last)
        this.animaling = true;
    this.ctx.clearRect(0, 0, this.width, this.height);
    this.drawAxis();
    this.drawBackground();
    this.drawLines(last, true);
    if (last) {
        this.animaling = false;
        this.afterAnimal();
    }
},
beforeAnimal : function() {
    this.products.disable();
    this.years.disable();
},
afterAnimal : function() {
    this.products.enable();
    this.years.enable();
},
drawLines : function(last, anim) {
    if (this.deleteAllDot == true && this.dotsEl) {
        this.dotsEl.select('div', true).remove();
        this.deleteAllDot = false;
    }
    if (!this.dotsEl) {
        this.dotsEl = Ext.get(this.ct).createChild();
        this.dotsEl.position('absolute');
        // this.dotsEl.setStyle('border', "1px solid #FF0000");
        this.dotsEl.setSize(this.width, 1);
        this.dotsEl.setLeftTop(0, 0);
        this.deleteAllDot = false;
    }

    for (i = 0; i < this.series.length; i++) {
        this.drawLine(i, anim, last);
    }
},
getYLen : function(line, i, rate, last) {
    return (last ? line.values[i] : line.tempValues[i]) * rate;
},
drawLine : function(index, anim, last) {
    var line = this.series[index], len = line.values.length;;
    var rate = this.cBox.h / this.yRange, yoffset = this.yMin * rate;
    if (anim === false) {
        // line.tempValues = line.values;//注意不能这样用 会改变values值
        for (var i = 0; i < line.values.length; i++) {
            line.tempValues[i] = line.values[i];
        }
    }
    if (!len)
        return;
    var yLen = this.getYLen(line, 0, rate, last), bBase = this.cBox.b
            + yoffset;
    var x = this.cBox.x, y = bBase - yLen;
    this.ctx.strokeStyle = line.color;
    this.ctx.lineWidth = line.width;

    this.ctx.beginPath();
    var tx = x, ty = y;
    this.ctx.moveTo(tx, ty);
    for (var i = 1; i < len; i++) {
        yLen = this.getYLen(line, i, rate, last)
        tx += this.xStep, ty = bBase - yLen;
        this.ctx.lineTo(tx, ty);
    }
    this.ctx.stroke();

    tx = x, ty = y;
    for (var i = 1; i < len; i++) {
        yLen = this.getYLen(line, i, rate, last)
        tx += this.xStep;
        ty = bBase - yLen;
        this.drawDot(tx, ty, 3, line, last, i);
    }
    if (anim) {
        for (var i = 0; i < len; i++) {
            line.tempValues[i] += (line.values[i] - line.avgValue)
                    / this.repeat;
        }
    }

},
drawDot : function(x, y, rad, line, last, dotindex) {
    this.ctx.beginPath();
    this.ctx.fillStyle = line.color;
    this.ctx.arc(x, y, rad, 0, Math.PI * 2, false);
    this.ctx.fill();
    if (last) {
        var div = this.dotsEl.createChild();
        div.position('absolute');
        // div.setStyle('border', "1px solid #FF0000");
        div.setSize(10, 10);
        div.setLeftTop(x - 5, y - 5);
        // div.setStyle('cursor', "move");

        div.on('mouseover', this.showTip.createDelegate(this, [line, 3,
                dotindex], 0), this, {
            delay : 100
        });
        div.on('mouseout', this.hideTip.createDelegate(this, [line, 2,
                dotindex], 0), this, {
            delay : 100
        });

    }
},
showTip : function(line, size, dotindex, e) {
    if (this.tipHide == true) {
        line.width = size;
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.drawAxis();
        this.drawBackground();
        this.drawLines(true, false);
        var data = {
            name : line.product.data['name'],
            avg : Math.round(line.avgValue),
            now : Math.round(line.values[dotindex]),
            year : line.label
        };
        var text = this.msgTpl.applyTemplate(data);
        this.dotDetail.show(text, e.getXY());
        this.tipHide = false;
    }
},
hideTip : function(line, size, dotindex, e) {
    if (this.tipHide == false) {
        line.width = size;
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.drawAxis();
        this.drawBackground();
        this.drawLines(true, false);
        this.dotDetail.hide();
        this.tipHide = true;
    }
},
initValue : function() {
    // this.yMax = this.yMin = null;
    this.xLength = 0;
    for (i = 0; i < this.series.length; i++) {
        var line = this.series[i], vlen = line.values.length;
        vlen > this.xLength ? this.xLength = vlen : '';
        for (j = 0; j < vlen; j++) {
            var value = line.values[j];
            if ((this.yMin == null) || (value < this.yMin))
                this.yMin = value;
            if ((this.yMax == null) || (value > this.yMax))
                this.yMax = value;
        }
    }
    this.yRange = this.yMax - this.yMin;
    this.xStep = this.cBox.w / (this.xLength - 1);
    this.xColumns = this.xLabels.length;
},
initPos : function() {
    this.cBox = {
        x : this.width * 0.08,
        y : this.height * 0.05,
        w : this.width * 0.85,
        h : this.height * (this.legend ? 0.75 : 0.85)
    };
    this.cBox.t = this.cBox.y;
    this.cBox.l = this.cBox.x;
    this.cBox.b = this.cBox.y + this.cBox.h;
    this.cBox.r = this.cBox.x + this.cBox.w;

},
initLines : function() {
    for (var i = 0; i < this.series.length; i++) {
        this.initLine(this.series[i]);
    }
},
init : function() {
    this.initPos();
    this.initLines();
    this.initValue();
    this.timeCount = 0;
},
draw : function() {
    this.init();
    this.drawAxis();
    this.drawBackground();
    this.drawLegend();
    // this.drawLines(true, false);
    Ext.TaskMgr.start( {
        run : function() {
            this.drawAnimLines();
        },
        interval : 100,
        repeat : this.repeat,
        scope : this
    });

},
getProductsCheckId : function() {
    for (var i = 0; i < this.radioItems.length; i++) {
        var p = this.radioItems[i].el.dom;
        if (p.checked)
            return p.value;
    }
},
setData : function(index) {
    this.series = [];
    var product = this.ds.getAt(index);
    if (!product)
        return;
    for (var i = 0; i < product.data['data'].length; i++) {
        var line = product.data['data'][i];
        this.addLine(line[0], line[1], line[2], this.defaultLineWidth, i,
                product);
    }
},
addData : function(index) {
    var product = this.ds.getAt(this.getProductsCheckId());
    var line = product.data['data'][index];
    if (this.series.indexOf(line) == -1) {
        this.addLine(line[0], line[1], line[2], this.defaultLineWidth,
                index, product);
    }
},
removeData : function(index) {
    for (var i = 0; i < this.series.length; i++) {
        if (this.series[i].id == index) {
            this.series.remove(this.series[i]);
        }
    }
},
choice : function(c, type) {
    var v = c.el.dom.value;
    switch (type) {
        case 'all' :
            this.setData(parseInt(v));
            this.createYears(this.getProductsCheckId());
            break;
        case 'add' :
            this.addData(parseInt(v));
            break;
        case 'del' :
            this.removeData(parseInt(v));
            break;
    }
    this.deleteAllDot = true;
    this.yMin = null;
    this.yMax = null;
    this.draw();
},
createProducts : function() {
    var checked;
    if (!this.radioItems)
        this.radioItems = [];
    for (var i = 0; i < this.ds.getCount(); i++) {
        var r = this.ds.getAt(i);
        if (r.data['state'] == 1)
            checked = i;
        var name = '<font color="' + r.data['color'] + '">'
                + r.data['name'] + '</font>';
        var product = new Ext.form.Radio( {
            boxLabel : name,
            name : '_cg',
            inputValue : i,
            checked : !!r.data['state']
        });
        product.on('check', function(t, c) {
            c ? this.choice(t, 'all') : '';
        }, this);
        this.radioItems.push(product);
    }
    this.products = new Ext.form.RadioGroup( {
        columnWidth : '.5',
        items : this.radioItems
    });
    this.createYears(checked);

},
createYears : function(checked) {
    var data = (this.ds.getAt(checked)).data['data'];
    if (!this.checkboxItems)
        this.checkboxItems = [];
    for (var i = 0; i < data.length; i++) {
        var line = data[i], name = '<font color="' + line[1] + '">'
                + line[0] + '</font>';
        var year = new Ext.form.Checkbox( {
            boxLabel : name,
            inputValue : i,
            name : '_ck',
            checked : true
        })
        year.on('check', function(t, c) {
            this.choice(t, c ? 'add' : 'del');
        }, this);
        this.checkboxItems.push(year);
    }
    var oldYears = this.years;
    this.years = new Ext.form.CheckboxGroup( {
        columnWidth : '.5',
        columns : 3,
        items : this.checkboxItems
    });
    if (this.legendPanel) {
        this.legendPanel.remove(this.yearsoldYears);
        this.legendPanel.insert(1, this.years);
        this.legendPanel.doLayout();
    }
},
drawLegend : function() {
    if (this.legend == true && !this.legendPanel) {
        this.createProducts();
        this.legendPanel = new Ext.FormPanel( {
            layout : 'column',
            width : this.cBox.w,
            border : false,
            defaults : {
                border : false
            },
            floating : true,
            shadow : false,
            x : this.cBox.x,
            y : this.cBox.b + this.xText.getHeight() + this.xTextOffset
                    + this.legendOffset,
            height : 30,
            frame : true,
            items : [this.products, this.years]
        });
        this.legendPanel.render(this.ct);

    }

}

});
Ext.onReady(function() {
Ext.QuickTips.init();
Ext.lib.Ajax.defaultPostHeader += ";charset=utf-8";
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
var reader = new Ext.data.ArrayReader( {
fields : [ {
name : 'index',
type : 'int'
}, {
name : 'name',
type : 'string'
}, {
name : 'state',
type : 'int'
}, {
name : 'color',
type : 'string'
}, {
name : 'data'
}]
});
var data = [
[
1,
'小草',
1,
'#ff0000',
[
[
'2007',
'#4040FF',
[5, 10, 20, 10, 40, 52, 68, 70, 70, 60, 28,
48]],
[
'2008',
'#FF00FF',
[8, 7, 12, 25, 24, 16, 36, 28, 28, 45, 28,
15]],
[
'2009',
'#8080FF',
[8, 7, 12, 20, 34, 16, 96, 25, 28, 56, 28,
95]]]],
[
2,
'大草',
0,
'#00ff00',
[
[
'2007',
'#4040FF',
[5, 10, 20, 10, 40, 52, 68, 70, 70, 60, 56,
45]],
[
'2008',
'#FF00FF',
[1, 20, 3, 2, 10, 12, 8, 10, 28, 45, 28, 21]],
[
'2009',
'#8080FF',
[8, 7, 12, 20, 24, 16, 36, 28, 28, 45, 76,
82]]]],
[
3,
'消食片',
0,
'#0000ff',
[
[
'2007',
'#4040FF',
[5, 10, 26, 10, 40, 52, 64, 70, 70, 60, 28,
45]],
[
'2008',
'#FF00FF',
[1, 20, 3, 2, 1, 4, 15, 12, 154, 10, 28, 12]],
[
'2009',
'#8080FF',
[8, 7, 12, 20, 24, 36, 36, 21, 28, 45, 28,
45]]]]]

var ds = new Ext.data.Store( {
    reader : reader,
    data : data
});

var line = new Ext.chart.Line( {
    width : 500,
    height : 270,
    ds : ds,
    xLabels : ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月',
            '11月', '12月']
});
var win = new Ext.Window( {
    width : 510,
    height : 315,
    title : '最近三年销售额对比',
    items : [line]
});
win.show();

});
//饼图
excanvas.js
// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Known Issues:
//
// * Patterns are not implemented.
// * Radial gradient are not implemented. The VML version of these look very
// different from the canvas one.
// * Clipping paths are not implemented.
// * Coordsize. The width and height attribute have higher priority than the
// width and height style values which isn't correct.
// * Painting mode isn't implemented.
// * Canvas width/height should is using content-box by default. IE in
// Quirks mode will draw the canvas using border-box. Either change your
// doctype to HTML5
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
// or use Box Sizing Behavior from WebFX
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Optimize. There is always room for speed improvements.

// only add this code if we do not already have a canvas implementation
if (!window.CanvasRenderingContext2D) {

(function () {

// alias some functions to make (compiled) code shorter
var m = Math;
var mr = m.round;
var ms = m.sin;
var mc = m.cos;

// this is used for sub pixel precision
var Z = 10;
var Z2 = Z / 2;

var G_vmlCanvasManager_ = {
init: function (opt_doc) {
var doc = opt_doc || document;
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
var self = this;
doc.attachEvent("onreadystatechange", function () {
self.init_(doc);
});
}
},

init_: function (doc) {
  if (doc.readyState == "complete") {
    // create xmlns
    if (!doc.namespaces["g_vml_"]) {
      doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml");
    }

    // setup default css
    var ss = doc.createStyleSheet();
    ss.cssText = "canvas{display:inline-block;overflow:hidden;" +
        // default size is 300x150 in Gecko and Opera
        "text-align:left;width:300px;height:150px}" +
        "g_vml_\\:*{behavior:url(#default#VML)}";

    // find all canvas elements
    var els = doc.getElementsByTagName("canvas");
    for (var i = 0; i < els.length; i++) {
      if (!els[i].getContext) {
        this.initElement(els[i]);
      //  alert(i);
      }
    }
  }
},

fixElement_: function (el) {
  // in IE before version 5.5 we would need to add HTML: to the tag name
  // but we do not care about IE before version 6
  var outerHTML = el.outerHTML;

  var newEl = el.ownerDocument.createElement(outerHTML);
  // if the tag is still open IE has created the children as siblings and
  // it has also created a tag with the name "/FOO"
  if (outerHTML.slice(-2) != "/>") {
    var tagName = "/" + el.tagName;
    var ns;
    // remove content
    while ((ns = el.nextSibling) && ns.tagName != tagName) {
      ns.removeNode();
    }
    // remove the incorrect closing tag
    if (ns) {
      ns.removeNode();
    }
  }
  el.parentNode.replaceChild(newEl, el);
  return newEl;
},

/**
 * Public initializes a canvas element so that it can be used as canvas
 * element from now on. This is called automatically before the page is
 * loaded but if you are creating elements using createElement you need to
 * make sure this is called on the element.
 * @param {HTMLElement} el The canvas element to initialize.
 * @return {HTMLElement} the element that was created.
 */
initElement: function (el) {
// el = this.fixElement_(el);
  el.getContext = function () {
    if (this.context_) {        
      return this.context_;
    }
    return this.context_ = new CanvasRenderingContext2D_(this);
  };

  // do not use inline function because that will leak memory

// el.attachEvent('onpropertychange', onPropertyChange);
// el.attachEvent('onresize', onResize);

  var attrs = el.attributes;
  if (attrs.width && attrs.width.specified) {
    // TODO: use runtimeStyle and coordsize
    el.getContext().setWidth_(attrs.width.nodeValue);
  el.style.width = attrs.width.nodeValue + "px";
  } else {
 //   el.width = el.clientWidth;
  }
  if (attrs.height && attrs.height.specified) {
    // TODO: use runtimeStyle and coordsize
    el.getContext().setHeight_(attrs.height.nodeValue);
    el.style.height = attrs.height.nodeValue + "px";
  } else {
    el.height = el.clientHeight;
  }
  //el.getContext().setCoordsize_()
  return el;
}

};

function onPropertyChange(e) {
var el = e.srcElement;

switch (e.propertyName) {
  case 'width':
    el.style.width = el.attributes.width.nodeValue + "px";
    el.getContext().clearRect();
    break;
  case 'height':
    el.style.height = el.attributes.height.nodeValue + "px";
    el.getContext().clearRect();
    break;
}

}

function onResize(e) {
var el = e.srcElement;
if (el.firstChild) {
el.firstChild.style.width = el.clientWidth + 'px';
el.firstChild.style.height = el.clientHeight + 'px';
}
}

G_vmlCanvasManager_.init();

// precompute "00" to "FF"
var dec2hex = [];
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) {
dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
}
}

function createMatrixIdentity() {
return [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]
];
}

function matrixMultiply(m1, m2) {
var result = createMatrixIdentity();

for (var x = 0; x < 3; x++) {
  for (var y = 0; y < 3; y++) {
    var sum = 0;

    for (var z = 0; z < 3; z++) {
      sum += m1[x][z] * m2[z][y];
    }

    result[x][y] = sum;
  }
}
return result;

}

function copyState(o1, o2) {
o2.fillStyle = o1.fillStyle;
o2.lineCap = o1.lineCap;
o2.lineJoin = o1.lineJoin;
o2.lineWidth = o1.lineWidth;
o2.miterLimit = o1.miterLimit;
o2.shadowBlur = o1.shadowBlur;
o2.shadowColor = o1.shadowColor;
o2.shadowOffsetX = o1.shadowOffsetX;
o2.shadowOffsetY = o1.shadowOffsetY;
o2.strokeStyle = o1.strokeStyle;
o2.arcScaleX_ = o1.arcScaleX_;
o2.arcScaleY_ = o1.arcScaleY_;
}

function processStyle(styleString) {
var str, alpha = 1;

styleString = String(styleString);
if (styleString.substring(0, 3) == "rgb") {
  var start = styleString.indexOf("(", 3);
  var end = styleString.indexOf(")", start + 1);
  var guts = styleString.substring(start + 1, end).split(",");

  str = "#";
  for (var i = 0; i < 3; i++) {
    str += dec2hex[Number(guts[i])];
  }

  if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) {
    alpha = guts[3];
  }
} else {
  str = styleString;
}

return [str, alpha];

}

function processLineCap(lineCap) {
switch (lineCap) {
case "butt":
return "flat";
case "round":
return "round";
case "square":
default:
return "square";
}
}

/**

  • This class implements CanvasRenderingContext2D interface as described by
  • the WHATWG.
  • @param {HTMLElement} surfaceElement The element that the 2D context should
  • be associated with
    */
    function CanvasRenderingContext2D_(surfaceElement) {
    this.m_ = createMatrixIdentity();

    this.mStack_ = [];
    this.aStack_ = [];
    this.currentPath_ = [];

    // Canvas context properties
    this.strokeStyle = "#000";
    this.fillStyle = "#000";

    this.lineWidth = 1;
    this.lineJoin = "miter";
    this.lineCap = "butt";
    this.miterLimit = Z * 1;
    this.globalAlpha = 1;
    this.canvas = surfaceElement;

    var el = surfaceElement.ownerDocument.createElement('div');
    el.style.width = surfaceElement.clientWidth + 'px';
    el.style.height = surfaceElement.clientHeight + 'px';
    el.style.overflow = 'hidden';
    el.style.position = 'absolute';
    surfaceElement.appendChild(el);

    this.element_ = el;
    this.arcScaleX_ = 1;
    this.arcScaleY_ = 1;
    };

    var contextPrototype = CanvasRenderingContext2D_.prototype;
    contextPrototype.clearRect = function() {
    this.element_.innerHTML = "";
    this.currentPath_ = [];
    };

    contextPrototype.beginPath = function() {
    // TODO: Branch current matrix so that save/restore has no effect
    // as per safari docs.

    this.currentPath_ = [];
    };

    contextPrototype.moveTo = function(aX, aY) {
    this.currentPath_.push({type: "moveTo", x: aX, y: aY});
    this.currentX_ = aX;
    this.currentY_ = aY;
    };

    contextPrototype.lineTo = function(aX, aY) {
    this.currentPath_.push({type: "lineTo", x: aX, y: aY});
    this.currentX_ = aX;
    this.currentY_ = aY;
    };

    contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
    aCP2x, aCP2y,
    aX, aY) {
    this.currentPath_.push({type: "bezierCurveTo",
    cp1x: aCP1x,
    cp1y: aCP1y,
    cp2x: aCP2x,
    cp2y: aCP2y,
    x: aX,
    y: aY});
    this.currentX_ = aX;
    this.currentY_ = aY;
    };

    contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
    // the following is lifted almost directly from
    // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
    var cp1x = this.currentX_ + 2.0 / 3.0 * (aCPx - this.currentX_);
    var cp1y = this.currentY_ + 2.0 / 3.0 * (aCPy - this.currentY_);
    var cp2x = cp1x + (aX - this.currentX_) / 3.0;
    var cp2y = cp1y + (aY - this.currentY_) / 3.0;
    this.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, aX, aY);
    };

    contextPrototype.arc = function(aX, aY, aRadius,
    aStartAngle, aEndAngle, aClockwise) {
    aRadius *= Z;
    var arcType = aClockwise ? "at" : "wa";

    var xStart = aX + (mc(aStartAngle) * aRadius) - Z2;
    var yStart = aY + (ms(aStartAngle) * aRadius) - Z2;

    var xEnd = aX + (mc(aEndAngle) * aRadius) - Z2;
    var yEnd = aY + (ms(aEndAngle) * aRadius) - Z2;

    // IE won't render arches drawn counter clockwise if xStart == xEnd.
    if (xStart == xEnd && !aClockwise) {
    xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
    // that can be represented in binary
    }

    this.currentPath_.push({type: arcType,
    x: aX,
    y: aY,
    radius: aRadius,
    xStart: xStart,
    yStart: yStart,
    xEnd: xEnd,
    yEnd: yEnd});

    };

    contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
    this.moveTo(aX, aY);
    this.lineTo(aX + aWidth, aY);
    this.lineTo(aX + aWidth, aY + aHeight);
    this.lineTo(aX, aY + aHeight);
    this.closePath();
    };

    contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
    // Will destroy any existing path (same as FF behaviour)
    this.beginPath();
    this.moveTo(aX, aY);
    this.lineTo(aX + aWidth, aY);
    this.lineTo(aX + aWidth, aY + aHeight);
    this.lineTo(aX, aY + aHeight);
    this.closePath();
    this.stroke();
    };

    contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
    // Will destroy any existing path (same as FF behaviour)
    this.beginPath();
    this.moveTo(aX, aY);
    this.lineTo(aX + aWidth, aY);
    this.lineTo(aX + aWidth, aY + aHeight);
    this.lineTo(aX, aY + aHeight);
    this.closePath();
    this.fill();
    };

    contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
    var gradient = new CanvasGradient_("gradient");
    return gradient;
    };

    contextPrototype.createRadialGradient = function(aX0, aY0,
    aR0, aX1,
    aY1, aR1) {
    var gradient = new CanvasGradient_("gradientradial");
    gradient.radius1_ = aR0;
    gradient.radius2_ = aR1;
    gradient.focus_.x = aX0;
    gradient.focus_.y = aY0;
    return gradient;
    };

    contextPrototype.drawImage = function (image, var_args) {
    var dx, dy, dw, dh, sx, sy, sw, sh;

    // to find the original width we overide the width and height
    var oldRuntimeWidth = image.runtimeStyle.width;
    var oldRuntimeHeight = image.runtimeStyle.height;
    image.runtimeStyle.width = 'auto';
    image.runtimeStyle.height = 'auto';

    // get the original size
    var w = image.width;
    var h = image.height;

    // and remove overides
    image.runtimeStyle.width = oldRuntimeWidth;
    image.runtimeStyle.height = oldRuntimeHeight;

    if (arguments.length == 3) {
    dx = arguments[1];
    dy = arguments[2];
    sx = sy = 0;
    sw = dw = w;
    sh = dh = h;
    } else if (arguments.length == 5) {
    dx = arguments[1];
    dy = arguments[2];
    dw = arguments[3];
    dh = arguments[4];
    sx = sy = 0;
    sw = w;
    sh = h;
    } else if (arguments.length == 9) {
    sx = arguments[1];
    sy = arguments[2];
    sw = arguments[3];
    sh = arguments[4];
    dx = arguments[5];
    dy = arguments[6];
    dw = arguments[7];
    dh = arguments[8];
    } else {
    throw "Invalid number of arguments";
    }

    var d = this.getCoords_(dx, dy);

    var w2 = sw / 2;
    var h2 = sh / 2;

    var vmlStr = [];

    var W = 10;
    var H = 10;

    // For some reason that I've now forgotten, using divs didn't work
    vmlStr.push(' <g_vml_:group',
    ' coordsize="', Z * W, ',', Z * H, '"',
    ' coordorigin="0,0"' ,
    ' style="width:', W, ';height:', H, ';position:absolute;');

    // If filters are necessary (rotation exists), create them
    // filters are bog-slow, so only create them if abbsolutely necessary
    // The following check doesn't account for skews (which don't exist
    // in the canvas spec (yet) anyway.

    if (this.m_[0][0] != 1 || this.m_[0][1]) {
    var filter = [];

    // Note the 12/21 reversal
    filter.push("M11='", this.m_[0][0], "',",
    "M12='", this.m_[1][0], "',",
    "M21='", this.m_[0][1], "',",
    "M22='", this.m_[1][1], "',",
    "Dx='", mr(d.x / Z), "',",
    "Dy='", mr(d.y / Z), "'");

    // Bounding box calculation (need to minimize displayed area so that
    // filters don't waste time on unused pixels.
    var max = d;
    var c2 = this.getCoords_(dx + dw, dy);
    var c3 = this.getCoords_(dx, dy + dh);
    var c4 = this.getCoords_(dx + dw, dy + dh);

    max.x = Math.max(max.x, c2.x, c3.x, c4.x);
    max.y = Math.max(max.y, c2.y, c3.y, c4.y);

    vmlStr.push("padding:0 ", mr(max.x / Z), "px ", mr(max.y / Z),
    "px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",
    filter.join(""), ", sizingmethod='clip');")
    } else {
    vmlStr.push("top:", mr(d.y / Z), "px;left:", mr(d.x / Z), "px;")
    }

    vmlStr.push(' ">' ,
    ' ' style="width:', Z * dw, ';',
    ' height:', Z * dh, ';"',
    ' cropleft="', sx / w, '"',
    ' croptop="', sy / h, '"',
    ' cropright="', (w - sx - sw) / w, '"',
    ' cropbottom="', (h - sy - sh) / h, '"',
    ' />',
    '');

    this.element_.insertAdjacentHTML("BeforeEnd",
    vmlStr.join(""));
    };

    contextPrototype.stroke = function(aFill) {
    this.element_.runtimeStyle.width = this.canvas.width;
    this.element_.runtimeStyle.height = this.canvas.height;
    var lineStr = [];
    var lineOpen = false;
    var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
    var color = a[0];
    var opacity = a[1] * this.globalAlpha;

    var W = 10;
    var H = 10;

    lineStr.push('<g_vml_:shape',
    ' fillcolor="', color, '"',
    ' filled="', Boolean(aFill), '"',
    ' style="position:absolute;width:', W, ';height:', H, ';"',
    ' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
    ' stroked="', !aFill, '"',
    ' strokeweight="', this.lineWidth, '"',
    ' strokecolor="', color, '"',
    ' path="');

    var newSeq = false;
    var min = {x: null, y: null};
    var max = {x: null, y: null};

    for (var i = 0; i < this.currentPath_.length; i++) {
    var p = this.currentPath_[i];

    if (p.type == "moveTo") {
    lineStr.push(" m ");
    var c = this.getCoords_(p.x, p.y);
    lineStr.push(mr(c.x), ",", mr(c.y));
    } else if (p.type == "lineTo") {
    lineStr.push(" l ");
    var c = this.getCoords_(p.x, p.y);
    lineStr.push(mr(c.x), ",", mr(c.y));
    } else if (p.type == "close") {
    lineStr.push(" x ");
    } else if (p.type == "bezierCurveTo") {
    lineStr.push(" c ");
    var c = this.getCoords_(p.x, p.y);
    var c1 = this.getCoords_(p.cp1x, p.cp1y);
    var c2 = this.getCoords_(p.cp2x, p.cp2y);
    lineStr.push(mr(c1.x), ",", mr(c1.y), ",",
    mr(c2.x), ",", mr(c2.y), ",",
    mr(c.x), ",", mr(c.y));
    } else if (p.type == "at" || p.type == "wa") {
    lineStr.push(" ", p.type, " ");
    var c = this.getCoords_(p.x, p.y);
    var cStart = this.getCoords_(p.xStart, p.yStart);
    var cEnd = this.getCoords_(p.xEnd, p.yEnd);

    lineStr.push(mr(c.x - this.arcScaleX_ * p.radius), ",",
                 mr(c.y - this.arcScaleY_ * p.radius), " ",
                 mr(c.x + this.arcScaleX_ * p.radius), ",",
                 mr(c.y + this.arcScaleY_ * p.radius), " ",
                 mr(cStart.x), ",", mr(cStart.y), " ",
                 mr(cEnd.x), ",", mr(cEnd.y));
    

    }

    // TODO: Following is broken for curves due to
    // move to proper paths.

    // Figure out dimensions so we can do gradient fills
    // properly
    if(c) {
    if (min.x == null || c.x < min.x) {
    min.x = c.x;
    }
    if (max.x == null || c.x > max.x) {
    max.x = c.x;
    }
    if (min.y == null || c.y < min.y) {
    min.y = c.y;
    }
    if (max.y == null || c.y > max.y) {
    max.y = c.y;
    }
    }
    }
    lineStr.push(' ">');

    if (typeof this.fillStyle == "object") {
    var focus = {x: "50%", y: "50%"};
    var width = (max.x - min.x);
    var height = (max.y - min.y);
    var dimension = (width > height) ? width : height;

    focus.x = mr((this.fillStyle.focus_.x / width) * 100 + 50) + "%";
    focus.y = mr((this.fillStyle.focus_.y / height) * 100 + 50) + "%";

    var colors = [];

    // inside radius (%)
    if (this.fillStyle.type_ == "gradientradial") {
    var inside = (this.fillStyle.radius1_ / dimension * 100);

    // percentage that outside radius exceeds inside radius
    var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside;
    

    } else {
    var inside = 0;
    var expansion = 100;
    }

    var insidecolor = {offset: null, color: null};
    var outsidecolor = {offset: null, color: null};

    // We need to sort 'colors' by percentage, from 0 > 100 otherwise ie
    // won't interpret it correctly
    this.fillStyle.colors_.sort(function (cs1, cs2) {
    return cs1.offset - cs2.offset;
    });

    for (var i = 0; i < this.fillStyle.colors_.length; i++) {
    var fs = this.fillStyle.colors_[i];

    colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ",");
    
    if (fs.offset > insidecolor.offset || insidecolor.offset == null) {
      insidecolor.offset = fs.offset;
      insidecolor.color = fs.color;
    }
    
    if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) {
      outsidecolor.offset = fs.offset;
      outsidecolor.color = fs.color;
    }
    

    }
    colors.pop();

    lineStr.push(' ' color="', outsidecolor.color, '"',
    ' color2="', insidecolor.color, '"',
    ' type="', this.fillStyle.type_, '"',
    ' focusposition="', focus.x, ', ', focus.y, '"',
    ' colors="', colors.join(""), '"',
    ' opacity="', opacity, '" />');
    } else if (aFill==true) {
    lineStr.push('');
    } else
    { lineStr.push(
    ' ' opacity="', opacity,'"',
    ' joinstyle="', this.lineJoin, '"',
    ' miterlimit="', this.miterLimit, '"',
    ' endcap="', processLineCap(this.lineCap) ,'"',
    ' weight="', this.lineWidth, 'px"',
    ' color="', color,'" />'
    );
    }

    lineStr.push("");

    this.element_.insertAdjacentHTML("beforeEnd", lineStr.join(""));

    // this.currentPath_ = [];
    };

    contextPrototype.fill = function() {
    this.stroke(true);
    }

    contextPrototype.closePath = function() {
    this.currentPath_.push({type: "close"});
    };

    /**

  • @private
    */
    contextPrototype.getCoords_ = function(aX, aY) {
    return {
    x: Z * (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]) - Z2,
    y: Z * (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) - Z2
    }
    };

    contextPrototype.save = function() {
    var o = {};
    copyState(this, o);
    this.aStack_.push(o);
    this.mStack_.push(this.m_);
    this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
    };

    contextPrototype.restore = function() {
    copyState(this.aStack_.pop(), this);
    this.m_ = this.mStack_.pop();
    };

    contextPrototype.translate = function(aX, aY) {
    var m1 = [
    [1, 0, 0],
    [0, 1, 0],
    [aX, aY, 1]
    ];

    this.m_ = matrixMultiply(m1, this.m_);
    };

    contextPrototype.rotate = function(aRot) {
    var c = mc(aRot);
    var s = ms(aRot);

    var m1 = [
    [c, s, 0],
    [-s, c, 0],
    [0, 0, 1]
    ];

    this.m_ = matrixMultiply(m1, this.m_);
    };

    contextPrototype.scale = function(aX, aY) {
    this.arcScaleX_ *= aX;
    this.arcScaleY_ *= aY;
    var m1 = [
    [aX, 0, 0],
    [0, aY, 0],
    [0, 0, 1]
    ];

    this.m_ = matrixMultiply(m1, this.m_);
    };

    /******** STUBS ********/
    contextPrototype.clip = function() {
    // TODO: Implement
    };

    contextPrototype.arcTo = function() {
    // TODO: Implement
    };

    contextPrototype.createPattern = function() {
    return new CanvasPattern_;
    };

    // Gradient / Pattern Stubs
    function CanvasGradient_(aType) {
    this.type_ = aType;
    this.radius1_ = 0;
    this.radius2_ = 0;
    this.colors_ = [];
    this.focus_ = {x: 0, y: 0};
    }

    CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
    aColor = processStyle(aColor);
    this.colors_.push({offset: 1-aOffset, color: aColor});
    };

    function CanvasPattern_() {}

    // set up externs
    G_vmlCanvasManager = G_vmlCanvasManager_;
    CanvasRenderingContext2D = CanvasRenderingContext2D_;
    CanvasGradient = CanvasGradient_;
    CanvasPattern = CanvasPattern_;

})();

} // if

//pie.js

function Pie(_div) {
var piejg = new jsGraphics(_div);
var colors = new Array();
colors[9] = "#0066FF";
colors[5] = "#996633";
colors[2] = "#80bb80";
colors[3] = "#FF0066";
colors[4] = "#9900FF";
colors[6] = "#006633";
colors[1] = "#8080FF";
colors[7] = "#000000";
colors[8] = "#CCFFFF";
colors[0] = "#FF8080";
colors[10] = "#066600";
colors[11] = "#666666";

this.start_x = 0;
this.start_y = 0;
this.width = 100;
this.height = 100;
this.desc_distance = 80;
this.desc_width = 10;
this.desc_height = 10;
this.IsShowPercentage = true;
this.IsShowShadow = true;
this.IsDescRight = true;
this.nextRow = 2;

this.drawPie = function(y_value, x_value) {
    if (this.IsShowShadow) {
        piejg.setColor("#666666");
        piejg.fillEllipse(this.start_x + 5, this.start_y + 5, this.width,
                this.height);
        piejg.setColor("#CCFFFF");
        piejg.fillEllipse(this.start_x, this.start_y, this.width,
                this.height);
    }
    var Percentage = new Array();
    var y_len = y_value.length;
    var x_len = x_value.length;
    var sum = 0;
    var perspective = new Array();
    var begin_perspective = 0;
    var end_perspective = 0;

    if (y_len != x_len) {
        alert("X and Y length of inconsistencies, errors parameters.");
        return;
    }
    for (var i = 0;i < y_len; i++) {
        sum += y_value[i];
    }
    for (var i = 0;i < y_len; i++) {
        if (isNaN(y_value[i])) {
            alert("y is not a number!");
            return;
        }
        perspective[i] = Math.max(Math.round(360 * y_value[i] / sum), 1);
        Percentage[i] = Math.round(100 * y_value[i] / sum);
        end_perspective += perspective[i];
        if (i == 0) {
            piejg.setColor(colors[i]);
            piejg.fillArc(this.start_x, this.start_y, this.width,
                    this.height, 0, end_perspective);
        } else {
            begin_perspective += perspective[i - 1];
            piejg.setColor(colors[i]);
            piejg.fillArc(this.start_x, this.start_y, this.width,
                    this.height, begin_perspective, end_perspective);
        }

    }
    var temp_x = 0;
    var temp_y = 0;
    if (this.IsDescRight) {
        for (var i = 0;i < x_len; i++) {
            temp_x = this.width + 10 + this.start_y;
            temp_y = this.start_y + (i - x_len / 2 + 1 / 2)
                    * (this.height / x_len) + this.height / 2;
            // temp_y = this.start_y+(i+1)*(this.height/x_len);
            piejg.setColor(colors[i]);
            piejg.fillRect(temp_x, temp_y, this.desc_width,
                    this.desc_height);
            if (this.IsShowPercentage) {
                piejg.drawString(x_value[i] + "[" + Percentage[i] + "%]",
                        temp_x + this.desc_width, temp_y);
            } else {
                piejg.drawString(x_value[i], temp_x + this.desc_width,
                        temp_y);
            }
        }
    } else {
        for (var i = 0;i < x_len; i++) {
            temp_x = i * this.desc_distance + this.start_x;
            temp_y = this.height + 10 + this.start_y;
            if (i - this.nextRow >= 0) {
                temp_x = (i - this.nextRow) * this.desc_distance
                        + this.start_x;
                temp_y = this.height + 10 + 30 + this.start_y;

            }
            if (i - this.nextRow * 2 >= 0) {
                temp_x = (i - this.nextRow * 2) * this.desc_distance
                        + this.start_x;
                temp_y = this.height + 10 + 60 + this.start_y;

            }
            if (i - this.nextRow * 3 >= 0) {
                temp_x = (i - this.nextRow * 3) * this.desc_distance
                        + this.start_x;
                temp_y = this.height + 10 + 90 + this.start_y;

            }
            piejg.setColor(colors[i]);
            piejg.fillRect(temp_x, temp_y, this.desc_width,
                    this.desc_height);
            if (this.IsShowPercentage) {
                piejg.drawString(x_value[i] + "[" + Percentage[i] + "%]",
                        this.desc_width + 3 + temp_x, temp_y);
            } else {
                piejg.drawString(x_value[i], this.desc_width + 3 + temp_x,
                        temp_y);
            }
        }
    }
    piejg.paint();

};
this.clearPie = function() {
    piejg.clear();
};

}