手机
当前位置:查字典教程网 >编程开发 >Javascript教程 >javascript使用smipleChart实现简单图表
javascript使用smipleChart实现简单图表
摘要:支持线性图区域图柱状图饼图支持多浏览器用到的是svgvml复制代码代码如下:smipleChart.cc{height:450px;widt...

支持 线性图 区域图 柱状图 饼图

支持多浏览器

用到的是svg vml

复制代码 代码如下:

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

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>smipleChart</title>

<style type="text/css">

.cc{

height:450px; width:800px; border:1px solid #999; position:relative; margin:20px;

}

</style>

</head>

<body>

<div id='t'></div>

<div id='t1'></div>

<div id='line'></div>

<div id='area'></div>

<div id='zhu'></div>

<div id='zhu1'></div>

<div id='segmentx'></div>

<div id='segmenty'></div>

<div id='pie'></div>

<div id='pies'></div>

<div id='vv'></div>

<script type="text/javascript">

(function(doc,undefined){

var win = this,

uuuid = -1,

hasSVG = win.SVGAngle || doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),

isIE = /msie/i.test(navigator.userAgent) && !win.opera,

path = hasSVG?'d':'path',

seal = hasSVG?'z':'e',

math = Math,

mathRound = math.round,

mathFloor = math.floor,

mathCeil = math.ceil,

mathMax = math.max,

mathMin = math.min,

mathAbs = math.abs,

mathCos = math.cos,

mathSin = math.sin,

M = 'M',

L = 'L';

win.$$ = function(Id){

return document.getElementById(Id);

};

win.extend = function(){

var target = arguments[0] || {}, i = 1, length = arguments.length, deep = true, options;

if ( typeof target === "boolean" ) {

deep = target;

target = arguments[1] || {};

i = 2;

}

if ( typeof target !== "object" && Object.prototype.toString.call(target)!="[object Function]")

target = {};

for(;i<length;i++){

if ( (options = arguments[ i ]) != null )

for(var name in options){

var src = target[ name ], copy = options[ name ];

if ( target === copy )

continue;

if ( deep && copy && typeof copy === "object" && !copy.nodeType ){

target[ name ] = arguments.callee( deep, src || ( copy.length != null ? [ ] : { } ), copy );

}

else if(copy !== undefined)

target[ name ] = copy;

}

}

return target;

};

win.each = function ( object, callback, args ) {

var name, i = 0, length = object.length;

if ( args ) {

args = Array.prototype.slice.call(arguments).slice(2);

if ( length === undefined ) {

for ( name in object )

if ( callback.apply( object[ name ],[name,object[ name ]].concat(args) ) === false )

break;

} else

for ( ; i < length; i++)

if ( callback.apply( object[ i ],[i,object[ i ]].concat(args)) === false ) //

break;

} else {

if ( length === undefined ) {

for ( name in object )

if ( callback.call( object[ name ], name, object[ name ] ) === false )

break;

} else

for ( var value = object[0];

i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}

}

return object;

};

win.contains = function(p,c){

if(!p||!c)return false;

if(p===c)return true;

return isIE

? p.contains(c)

: p.compareDocumentPosition(c)==20

? true

: false;

};

//---------------------------------------------------------------

function processPoint( x ){

return isIE ? ~~x.toFixed(0) : ~~x.toFixed(0) + 0.5;

};

function calTextLen(txt, cssStr){

var span = doc.createElement('span');

if(cssStr){

typeof cssStr === 'string'

? span.style.cssText = cssStr

: extend(span.style,cssStr);

}else{

extend(span.style,{

fontSiz : '12px',

fontFamily : '"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif'

});

}

span.innerHTML = txt || '';

span.style.visibility = 'hidden';

doc.body.appendChild(span);

var width = span.offsetWidth,

height = span.offsetHeight;

doc.body.removeChild(span);

return {w:width,h:height};

};

function angle(r,center,o,jingdu){

var hudu = Math.PI*2*(o/360),

x = center[0]+ r*Math.sin(hudu),

y = center[1]+ -r*Math.cos(hudu);

return [x.toFixed(jingdu||0),y.toFixed(jingdu||0)];

}

function xx(a,b,lineNum){

var t = 1000,

stf = ((b*t-a*t)/lineNum)/t,

arr = [1,2,2.5,5,10],

c = 1,

v;

// 分割线的基数是[1,2,2.5,5,10] 这个步骤是查找 间隔 属于哪个范围

if(stf<arr[0]){

while( stf<arr[0] ){

c = c*10;

arr[0]=arr[0]/c;

}

each([1,2,2.5,5,10],function(i,o){

arr[i]= o/c;

});

}else if(stf>arr[4]){

while( stf>arr[4] ){

c = c*10;

arr[4] = arr[4]*c;

}

each([1,2,2.5,5,10],function(i,o){

arr[i]= o*c;

});

}

//上面找到间隔后 找到间隔中最接近的一个

each(arr,function(i,o){

if(stf<=o){

v = o;

return false;

}

});

var bj = (mathAbs(a)*t)/(v*t),

ba = 0,

isZ = bj!==parseInt(bj);

isZ

&&a>0

? ba = -a%v*t

: ba = (mathAbs(a)%v-v)*t;

a = (a*t+ba)/t;

b = (b*t+(b%v===0?0:(v-b%v))*t)/t;

//看看还剩几条线没有画

var num = Math.max(0,lineNum - Math.round((b-a)/v));

if(a>=0){

//坐标比较整数化

if(a!=0&&num!=0&&a%10!==0){

while(a!=0&&num!=0){

a = (a*t-v*t)/t;

num--;

if((a*t-v*num*t)/10000>0&&a%10===0)

break;

}

}

if(num!=0){

while(num!==0){

b = (b*t+v*t)/t

num--;

}

}

}else{

//坐标比较整数化

if(b<0&&num!=0){

while(b!=0&&num!=0&&b%10!==0){

b = (b*t+v*t)/t;

num--;

if((b*t+v*num*t)/t<0&&b%10===0)

break;

}

}

if(num!=0){

while(num!==0){

a = (a*t-v*t)/t

num--;

}

}

}

return {min:a,max:b,stf:v};

}

//---------------------------------------------------------------------------------------------------------------

//对svg vml元素的一些创建 修改属性 样式 删除 == 一些的操作

win.vector = function(){};

vector.prototype = {

$c : function(graphic,nodeName){

this.element = this[0] = doc.createElementNS('http://www.w3.org/2000/svg', nodeName);

this.graphic = graphic;

return this;

},

attr:function(hash,val){

var elem = this.element,

key,

value;

if(typeof hash === 'string'){

if(val === undefined){

return elem.getAttribute(hash);

}else{

elem.setAttribute(hash, val);

return this;

}

} else {

for(key in hash){

value = hash[key];

if(key === path){

value && value.join

&&(value = value.join(' '));

/(NaN| |^$)/.test(value)

&&(value = 'M 0 0');

}

elem.setAttribute(key, value)

}

}

return this;

},

css: function(hash){

for(var key in hash){

isIE && key == "opacity"

? this[0].style['filter'] = "alpha(opacity="+ hash[key] * 100+")"

: this[0].style[key] = hash[key];

}

return this;

},

on: function(eventName, handler){

var self = this;

/*this.element.addEventListener(eventName,function(){

handler.call(self)

},false);*/

this.element['on' + eventName] = function(e){

e = e || win.event;

handler.call(self,e);

}

return this;

},

appendTo:function(parent){

if(parent){

parent.element

? parent.element.appendChild(this.element)

: parent.appendChild(this.element)

} else {

this.graphic.container.appendChild(this.element);

}

return this;

},

addText: function(str){

var elem = this.element;

if(elem.nodeName === 'text'){

elem.appendChild(doc.createTextNode(str+''));

}

return this;

},

setOpacity : function(v){

this.attr('fill-opacity',v);

return this;

},

setSize : function(v){

this[0].nodeName==='circle'

? this.attr('r',4+(v===0?0:2))

: this.attr({'stroke-width':v});

return this;

},

toFront: function() {

this[0].parentNode.appendChild(this[0]);

return this;

},

show:function(){

this[0].style.display = 'block';

return this;

},

hide:function(){

this[0].style.display = 'none';

return this;

},

destroy : function(){

//销毁节点......................

var node = this[0] || this;

node.onmouseover = node.onmouseout = node.onclick = null;

node.parentNode

&&node.parentNode.removeChild(node);

return this;

}

};

//---------------------------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------------------

//如果是vml修改其中的一些方法

if(!hasSVG){

//-------------创建vml环境-----------------

doc.createStyleSheet().addRule(".vml", "behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px");

!doc.namespaces.vml && !+"v1";

doc.namespaces.add("vml", "urn:schemas-microsoft-com:vml");

//-------------修改一些方法-----------------

extend(vector.prototype,{

$c : function(graphic,nodeName){

var name = nodeName || 'shape';

this.element= this[0] = (name === 'div' || name === 'span')

? doc.createElement(name)

: doc.createElement('<vml:'+name+'>');

this.graphic = graphic;

return this;

},

/*on : function(eventName, handler){

var self = this;

this.element.attachEvent("on" + eventName,function(){

handler.call(self);

});

return this;

},*/

addText : function(txt){

this[0].innerHTML = txt || '';

return this;

},

setSize : function(v){

this[0].strokeWeight = v;

return this;

},

setOpacity : function(v){

this.opacity.opacity=v;

return this;

}

});

}

//---------------------------------------------------------------------------------------------------

//画图类

//------------------------------------------------------------

win.smipleChart = function(){

this.init.apply(this,arguments);

};

smipleChart.list = [];

smipleChart.timer = null;

smipleChart.lazyLoad = function(id){

id = id || '0'

smipleChart.list[id]

&&smipleChart.list[id].loadMe();

};

smipleChart.prototype = {

options : {

charts : {

paddingRight : 20,

radius : 200,

style : {

fontFamily : '"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif',

fontSize : '12px',

background : '#FFFFFF'

}

},

title : {

text : '',

y : 10,

style : {

fontFamily:'Verdana,Arial,Helvetica,sans-serif',

fontSize:'16px',

fontWeight:'bold'

}

},

subTitle : {

text: '',

y: 30,

style : {

fontFamily:'Verdana,Arial,Helvetica,sans-serif',

fontSize:'12px',

color: '#111'

}

},

yUnit : {

text : '',

style : {

fontFamily:'Verdana,Arial,Helvetica,sans-serif',

fontSize:'12px',

color: '#111'

},

lineNum :10

}

},

init : function(container,options){

clearTimeout(smipleChart.timer)

var self = this;

this.width = container.offsetWidth;

this.height = container.offsetHeight;

this.currList = {};

this.uuuid = ++uuuid;

this.timer = null;

//主要画图组的集合 形式

//{id : {dom:xx,show:true}}

this.mainGroup = {};

//分段的时候要用到的 知道哪些是隐藏了的 因为要涉及到重绘

this.hideList = {};

//svg 里面画图 必须有一个svg标签 vml就用div了

this.container = hasSVG

? new vector().$c(1,'svg')

.attr({

xmlns : 'http://www.w3.org/2000/svg',

version : '1.1',

width : this.width,

height : this.height

})

.css({fontSize : '12px'})

.appendTo(container)

: new vector().$c(1,'div')

.css({

fontSize : '12px',

width : this.width +'px',

height : this.height+'px'

})

.appendTo(container);

this.loading = container.appendChild(doc.createElement('img'));

this.loading.setAttribute('src','http://images.cnblogs.com/cnblogs_com/wtcsy/192373/r_loading.gif');

this.loading.style.position = 'absolute';

this.loading.style.top = container.offsetHeight/2- this.loading.offsetHeight/2+'px';

this.loading.style.left = container.offsetWidth/2- this.loading.offsetWidth/2+'px';

var c = extend(true,{},this.options),

opts = this.opts = extend(true,c,options),

style = extend(opts.charts.style,{

width : this.width,

height : this.height

});

smipleChart.list[this.uuuid] = this;

smipleChart.timer = setTimeout(function(){

smipleChart.lazyLoad();

},200);

},

loadMe : function(){

var opts = this.opts,

self = this,

type = opts.charts.type;

this.container = this.container

.on('mouseout',function(e){

var elem = e.relatedTarget || e.toElement;

if(!contains(this[0],elem)){

self.hideTooltip();

self.currList.dot

&&self.currList.dot.setSize(0);

self.currList.line

&&self.currList.line.setSize(1.5);

self.currList = {};

}

})

.css({display:'none'})[0];

//计算绘画盘子的时候需要的一些参数

this.getDrawArea()

.createTooltip() //创建提示信息的框框

.drawTitle() //画标题

//画盘子

'line,area,pie'.indexOf(type)>=0

&&(opts.charts.panel = 'x');

' pie,pies'.indexOf(type)<0

&&this.drawPanel();

this.drawLegend(opts.legend.type); //画色块条

var type = {

line : 'drawLine',

area : 'drawArea',

columns : 'drawColumns',

pie : 'drawPie',

pies : 'drawPies',

segment : 'drawSegment'

}[opts.charts.type];

//开始画图..............

this[type]();

//删除节点

this.loading.parentNode.removeChild(this.loading);

//断开引用

this.loading = null;

this.container.style.display = '';

setTimeout(function(){

smipleChart.lazyLoad((++self.uuuid)+'');

},10)

},

createElement : function(nodeName){

return new vector().$c(this,nodeName);

},

group: function(name){

return this.createElement(hasSVG?'g':'div').attr('mark',name);

},

getDrawArea : function(){

var opts = this.opts,

width = this.width,

height = this.height,

title = opts.title,

subTitle = opts.subTitle,

area = {

// 去掉坐标轴左边的刻度文本宽度(预估) 80为定值 左边只留80的间距

areaWidth : width - 80,

// 去掉坐标轴底下的文本和标线的高度

areaHeight : height - 40,

//原点的X位置 下面会计算到

startX : 0,

//原点的Y位置 下面会计算到

startY : 0,

//中心的x坐标 画饼图的时候需要知道圆心的位置

centerX: 0,

//中心的y坐标 画饼图的时候需要知道圆心的位置

centerY: 0

};

//如果主标题存在 减去主标题的高度 否则 减去10的高

area.areaHeight -=(title.text !== '')

? title.y

: 10;

// 去掉副标题高度

area.areaHeight -=(subTitle.text !== '')

? subTitle.y

: 10

area.startX = 80;

area.startY = height - 40;

//圆心的位置

area.centerX = width / 2;

area.centerY = height / 2;

//右边留一些空隙

area.areaWidth -=20;

//上边也留一些间距

area.areaHeight -=15;

opts.area = area;

return this;

},

drawTitle : function(){

var opts = this.opts,

self = this,

arr = [opts.title,opts.subTitle,opts.yUnit],

//3个标题坐标的位置的基本参数

config = [

{

x : this.width / 2,

y : opts.title.y

},

{

x : this.width / 2,

y : opts.subTitle.y

},

{

x : opts.yUnit.x,

y : this.height / 2 - 20

}

],

tpanel = this.group('title')

.appendTo();

each(arr,function(i,title){

var text = title.text;

if(text){

var elem = self.baseDraw.span(self,{

'text-anchor':'left',

x : mathMax(config[i].x - calTextLen(text,title.style).w/2,10),

y : config[i].y

},calTextLen(title.text,title.style).h)

.css(title.style)

.addText(text)

.appendTo(tpanel);

//如果为2的时候 就说明是副标题 将它竖过来

if(i===2){

hasSVG

? elem.attr({transform : 'rotate(270, '+(opts.yUnit.x+10)+', ' + self.height / 2 + ')'})

: (elem.element.style.filter ='progid:DXImageTransform.Microsoft.BasicImage(rotation=3)')

}

}

});

return this;

},

//画盘子 比较麻烦

drawPanel : function(type){

varopts = this.opts,

self = this,

area = opts.area,

chartsType = opts.charts.type,

isSegment = chartsType === 'segment',

//盘子的类型 是横盘子 还是纵盘子

type = opts.charts.panel || 'x';

// 底板

var drawAreaWidth = area.areaWidth,

drawAreaHeight = area.areaHeight,

//原点的坐标

startX = area.startX,

startY = area.startY;

var allData = [],

minValue = 0,

maxValue = 10,

//线的条数 只能在1到10之间

lineNum = mathMin(10,mathMax(opts.yUnit.lineNum,1)),

staff;

//组合所有的数据

each(opts.chartData,function(i,o){

// 如果是柱状图 是对所有的数据求和

isSegment

? each(o.data,function(j,d){

allData[j]

? allData[j] = allData[j] + (~~d)

: allData[j] = ~~d;

})

: allData = allData.concat(o.data)

});

//给所有的数据排序 为了下面求最大值 最小值

allData.sort(function(a,b){return a-b});

//求出最大值 最小值

maxValue = allData[allData.length - 1];

each(allData,function(i,o){

if(o!==null){

minValue = o;

return false;

}

});

//主盘子容器

var panel = this.group('panel').appendTo();

var result = xx(minValue,maxValue,lineNum),

min = result.min,

max = result.max,

f = result.stf;

isSegment

&&(min = 0);

//表示画的是横坐标 或者是双坐标

if(type.toLowerCase()==='x'){

//横坐标单位间隔

varxPices = drawAreaWidth / opts.xUnit.units.length,

//单位间隔的中心点

offset = xPices / 2,

yPices = drawAreaHeight / lineNum;

//--------------------------------画横向的点和文字---------------------------------------------------------

var y = hasSVG?5:10,

t = 1000,

span;

each(opts.xUnit.units,function(i,d){

self.baseDraw.path(self,{

border : 1,

borderColor : '#C0C0C0',

isfill : false,

path : [

M,

processPoint(startX + (i * xPices)),

processPoint(startY),

L,

processPoint(startX + (i*xPices)),

processPoint(startY + 5)

]

}).

appendTo(panel);

span = self.baseDraw.span(self,{

x : startX + offset + (i * xPices),

y : startY+y,

'text-anchor':'middle'

})

.css({

fontFamily : 'Verdana,Arial,Helvetica,sans-serif',

fontSize : '12px'

})

.addText(opts.xUnit.units[i])

.appendTo(panel)[0];

!hasSVG

&&(span.style.left = parseInt(span.style.left) - span.offsetWidth/2+'px');

});

//--------------------------------画纵向的点和文字-----------------------------------------------------------------------

for(i=0;i<=lineNum;i++){

self.baseDraw.path(self,{

border : 1,

borderColor : '#C0C0C0',

isfill : false,

path : [M, startX, processPoint(startY - (i * yPices)), L, processPoint(startX + drawAreaWidth), processPoint(startY - (i *yPices))]

})

.css({zIndex:-10})

.appendTo(panel);

var span = self.baseDraw.span(self,{

x : startX - 15,

y : startY - i * yPices-calTextLen(min+i*f+'').h/2,

'text-anchor':'middle'

})

.css({

'font-family' : 'Verdana,Arial,Helvetica,sans-serif',

'font-size' : '12px',

width : '40px',

display : 'block',

textAlign : 'right'

})

.addText((min*t+(i*t*f/t)*t)/t+'')

.appendTo(panel)[0];

if(!hasSVG){

span.style.top = parseInt(span.style.top) + span.offsetHeight/2 -5+'px';

span.style.left = parseInt(span.style.left) -35+'px'

}

}

}else{

//横坐标单位间隔

varyPices = drawAreaHeight / (opts.xUnit.units.length),

//单位间隔的中心点

offset = Math.round(yPices / 2),

x = hasSVG ? 25 : 70,

y = hasSVG ? 0 : 5,

span

each(opts.xUnit.units,function(i,d){

self.baseDraw.path(self,{

border : 1,

borderColor : '#C0C0C0',

isfill : false,

path : [

M,

processPoint(startX-5),

processPoint(startY-i * yPices),

L,

processPoint(startX),

processPoint(startY-i * yPices),

]

})

.appendTo(panel);

span = self.baseDraw.span(self,{

x : startX - x,

y : startY -i * yPices-offset-calTextLen(d).h/2 + y,

'text-anchor':'middle'

})

.css({

fontFamily:'Verdana,Arial,Helvetica,sans-serif',

fontSize:'12px',

width : '60px',

textAlign:'right'

})

.addText(d)

.appendTo(panel)

});

var xPices = drawAreaWidth / lineNum;

for(var i=0;i<=lineNum;i++){

self.baseDraw.path(self,{

border : 1,

borderColor : '#C0C0C0',

isfill : false,

path : [

M,

processPoint(startX + (i * xPices)),

processPoint(startY),

L,

processPoint(startX + (i*xPices)),

processPoint(startY - drawAreaHeight)

]

}).

appendTo(panel);

self.baseDraw.span(self,{

x : startX - calTextLen(min+i*f+'').w/2 + i * xPices,

y : startY,

'text-anchor':'left'

})

.css({

fontFamily:'Verdana,Arial,Helvetica,sans-serif',

fontSize:'12px'

})

.addText(min+i*f+'')

.appendTo(panel);

}

}

//-----------------------------------------------------------------------------------------------------

//因为起点很可能不是从0开始的 所以在起点的时候要要加上到0那部分的值

var jianju =0;

if(min>0)jianju = min;

if(max<0)jianju = max;

startX = opts.charts.panel==='x' ? startX :startX-xPices*(min/f);

startY = opts.charts.panel==='x' ? startY + yPices*(min/f) : startY;

opts.draw = {

startX : startX, // X 轴起点

startY : startY , // Y 轴起点

xPices : xPices, // X 轴每份的宽度

yPices : yPices, // Y 轴每份的宽度

offset : offset, // X 单分中心点位置偏移量

jianjuY : jianju*yPices/f,

jianjuX : jianju*xPices/f,

feed : f // Y 轴的每份有多少

}

return this;

},

createTooltip : function(){

//一个组

this.tipC = this.group('tip')

.css({zIndex: 200,height:'20px',width:'20px',position:'absolute'})

.appendTo()

.hide()

//画一个框框baseDraw

this.tipBox = this.baseDraw.rect(this,{arc:0.22,fill:'#fff',border:2,borderColor:'#606060'})

.appendTo(this.tipC)

//因为svg里面的g可以直接定位 但是vml里面的group渲染很慢 所以改div 所以这里的父不一洋

var p = isIE ?this.tipBox :this.tipC;

this.tipTxtContainer = this.baseDraw.text(this,{fill:'#000000',x:5,y:19,'text-anchor':'left'})

.css({

fontFamily:'Verdana,Arial,Helvetica,sans-serif',

fontSize:'12px',

background: '#FFF'

})

.appendTo(p);

this.tipText = doc.createTextNode('');

this.tipTxtContainer[0].appendChild(this.tipText);

return this;

},

showTooltip : function(obj, x, y,data){

/*var txt = obj.name +':' + data,

size = calTextLen(txt,this.tipTxtContainer[0].style.cssText),

pos = {x : x - (size.w + 5 * 2)/2 ,y : y - 32};

this.tipC

.toFront()

.show();

if(hasSVG){

this.tipC.attr({transform:'translate('+pos.x+','+pos.y+')'});

this.tipBox

.attr({width : size.w + 5 * 2,height : size.h + 5 * 2,stroke : obj.color||'#606060'});

}else{

this.tipC.css({left:pos.x,top:pos.y});

this.tipBox

.css({width:size.w + 5 * 2,height : size.h + 5 * 2})

this.tipBox[0].strokeColor = obj.color||'#000';

}

this.tipText.nodeValue = txt || '';*/

clearTimeout(this.timer);

var txt = obj.name +':' + data,

self = this,

size = calTextLen(txt,this.tipTxtContainer[0].style.cssText),

pos = {x : x - (size.w + 5 * 2)/2 ,y : y - 32};

if(hasSVG){

self.tipBox

.attr({width : size.w + 5 * 2,height : size.h + 5 * 2,stroke : obj.color||'#606060'});

}else{

self.tipBox

.css({width:size.w + 5 * 2,height : size.h + 5 * 2})

self.tipBox[0].strokeColor = obj.color||'#000';

}

this.tipText.nodeValue = txt || '';

if(this.tipC[0].style.display === 'none'){

hasSVG

? self.tipC.attr({transform:'translate('+pos.x+','+pos.y+')',pos:pos.x+'-'+pos.y})

: self.tipC.attr({pos:pos.x+'-'+pos.y}).css({left:pos.x,top:pos.y});

this.tipC

.toFront()

.show();

}else{

var move = function(t,b,c,d){

return c*(t/=d)*t + b;

},

t = 0,

b = self.tipC.attr('pos').split('-'),

c = [pos.x,pos.y],

d = 5;

this.timer = setInterval(function(){

if(t<d){

t++;

var x = move(t,~~b[0],(~~c[0])-(~~b[0]),d),

y = move(t,~~b[1],(~~c[1])-(~~b[1]),d);

hasSVG

? self.tipC.attr({transform:'translate('+x+','+y+')',pos:x+'-'+y})

: self.tipC.attr({pos:x+'-'+y}).css({left:x,top:y});

}else{

clearTimeout(self.timer);

}

},1);

};

},

hideTooltip: function(){

this.tipC.hide();

},

drawLegend : function(type,redraw){

var self = this,

opts = this.opts,

isLine = opts.charts.type === 'line',

//颜色块的大小

t_width = 20,

t_height = 20,

//块之间的距离

t_space = 5,

datas = opts.chartData,

len = datas.length,

css = opts.legend.style,

//最大长度 如果是纵着的 需要最大的长度

maxWidth = 10,

maxHeight= 30,

//这个东西的位置

orig_pos = opts.legend.pos?opts.legend.pos:[2,2],

//显示隐藏组的函数

handle = function(i){

var g = self.mainGroup['chart'+i],

issegment = opts.charts.type==='segment';

if(g.show){

g.chart.hide();

g.show = false;

hasSVG

? this.attr({fill:'#ccc'})

: this[0].style.color = '#ccc';

//如果是分段图 是会涉及到重画的

if(issegment){

self.hideList[i] ='';

var mainGroup = self.mainGroup;

for(var name in mainGroup){

var parent = mainGroup[name].chart,

nodes = parent[0].childNodes,

len = nodes.length;

//销毁图上面画的东西

for(var i = len-1;i>=0;i--){

vector.prototype.destroy.call(nodes[i])

}

}

//重画

self.drawSegment();

}

}else{

g.chart.show();

g.show = true;

hasSVG

? this.attr({fill:'#000'})

: this[0].style.color = '#000'

if(issegment){

delete self.hideList[i];

var mainGroup = self.mainGroup;

for(var name in mainGroup){

var parent = mainGroup[name].chart,

nodes = parent[0].childNodes,

len = nodes.length;

for(var i = len-1;i>=0;i--){

vector.prototype.destroy.call(nodes[i])

}

}

self.drawSegment();

}

}

},

arr = [];

type = type ||'lateral';

var legendPanel = self.group('Legend')

.appendTo();

if(type==='lateral'){

//如果是横着的

var top = orig_pos[1] + 5,

th = hasSVG?0:3,

left = orig_pos[0] + 5;

each(datas, function(i,d){

left = i===0 ? left : t_space+left;

//计算所有left的位置

//如果是线性图 按线性图的方式画图

if(isLine){

self.baseDraw.path(self,{

border : 1.5,

borderColor : d.color,

isfill : false,

path : [

M,

left.toFixed(0),

(top+10).toFixed(0),

L,

(left+25).toFixed(0),

(top+10).toFixed(0)

]

})

.appendTo(legendPanel);

self.baseDraw[d.dotType || 'circle'](self,{

x : left+12,

y : top+10,

r : 4,

fillColor : d.color

})

.appendTo(legendPanel);

}else{

self.baseDraw.rect(self,{

arc : 0.1,

fill : d.color,

border : 1,

borderColor : d.color,

left : left,

top : top,

width : t_width+'px',

height : t_height+'px'

})

.appendTo(legendPanel)

}

left = left + t_width+2 + t_space;

var w = calTextLen(d.name,css).w

self.baseDraw.span(self,{

'text-anchor':'left',

x : left,

y : top+th

})

.css(extend(css,{cursor:'pointer'}))

.on('click',function(){

handle.call(this,i);

})

.addText(d.name)

.appendTo(legendPanel);

left = left + w;

});

this.baseDraw.rect(this,{

arc : 0.1,

fill : 'none',

border : 1.5,

borderColor : '#666666',

width : left+ t_space- orig_pos[0],

height : maxHeight,

left : orig_pos[0],

top : orig_pos[1]

})

.appendTo(legendPanel);

}else{

var top = orig_pos[1] + 5,

th = hasSVG?0:3,

left = orig_pos[0] + 5;

each(datas, function(i,d){

top = i===0 ? top : t_space + top;

self.baseDraw.rect(self,{

arc : 0.1,

fill : d.color,

border : 1,

borderColor : d.color,

left : left,

top : top,

width : t_width+'px',

height : t_height+'px'

})

.appendTo(legendPanel);

var h = calTextLen(d.name,css).h;

self.baseDraw.span(self,{

'text-anchor':'left',

x : left+t_width+2+t_space,

y : top+th

})

.css(extend(css,{cursor:'pointer'}))

.addText(d.name)

.on('click',function(){

//如果是多层饼图 不行进隐藏

if(opts.charts.type==='pies')return;

handle.call(this,i);

})

.appendTo(legendPanel);

top = top + h+ t_space;

maxWidth = Math.max(maxWidth,calTextLen(d.name,css).w);

});

this.baseDraw.rect(this,{

arc : 0.1,

fill : 'none',

border : 1.5,

borderColor : '#666666',

width : maxWidth+22+15,

height : top+t_space-orig_pos[1],

left : orig_pos[0],

top : orig_pos[1]

})

.appendTo(legendPanel);

}

return this;

},

drawLine : function(){

var self = this,

opts = this.opts,

draw = opts.draw;

each(opts.chartData,function(i,o){

var id = 'chart'+i,

lineGroup = self.group(id)

.appendTo();

self.mainGroup[id]={

chart : lineGroup,

show : true

};

var path = [M],

data = o.data,

line;

for(var i = 0,l = data.length; i < l ; i++){

if( data[i] == null){

//如果这个数据不存在 并且不是第一个数据 路径上加 M

if(path[path.length - 1] !== M)

path.push(M);

}else{

//如果不是第一个数据 路径添加L

i !== 0 && path.push("L");

//如果前面一个是null 并且不是第一个 把那个L去掉

if(i > 0 && data[i - 1] == null)

path.pop();

//计算出 点的x,y的位置

var x = draw.startX + draw.offset + (i * draw.xPices),

y = draw.startY - data[i] * (draw.yPices / draw.feed);

if(isIE){

x = parseInt(x);

y = parseInt(y);

}

path.push(x);

path.push(y);

//画点

var dotType = o.dotType||'circle';

self.baseDraw[dotType](self,{

x : x,

y : y,

r : 4,

fillColor : o.color

})

.attr({data:data[i],pos:x+'-'+(y-5)})

.css({zIndex:10,cursor:'pointer'})

.on('mouseover',(function(o,x,y){

return function(){

if(self.currList.dot){

if(self.currList.dot[0] === this[0])

return;

self.currList.dot.setSize(0);

self.currList.line.setSize(1.5);

}

this.setSize(2);

line.setSize(2.5);

var pos = this.attr('pos').split('-');

self.showTooltip(o,pos[0],pos[1],this.attr('data'));

self.currList.dot = this;

self.currList.line = line;

}

})(o,x,y))

/*.on('mouseout',function(){

this.setSize(0);

line.setSize(1.5);

})*/

.on('click',function(){lineGroup.toFront(); })

.appendTo(lineGroup);

}

};

//画折线

line = self.baseDraw.path(self,{

border : 1.5,

borderColor : o.color,

isfill : false,

path : path

})

.css({zIndex:5})

/*.on('mouseover',function(){

this.setSize(2.5);

})

.on('mouseout',function(){

this.setSize(1.5);

})*/

.on('click',function(){lineGroup.toFront();})

.appendTo(lineGroup);

});

return this;

},

drawArea : function(){

var self = this,

opts = this.opts,

draw = opts.draw;

each(opts.chartData,function(i,o){

var id = 'chart' + i,

areaGroup = self.group(id).appendTo();

self.mainGroup[id] = {chart : areaGroup,show : true};

//有2个路径 一个是区域的路径 一个是线的路径

var areaPath = [M, (draw.startX + draw.offset).toFixed(0), (draw.startY-draw.jianjuY).toFixed(0)],

path = [M],

data = o.data,

line;

for(var n=0,l = data.length;n<l;n++){

//如果数据是空的

var len = areaPath.length;

if( data[n] === null){

//如果前面的一个不是m 就重新画 所以加上 M

if(path[path.length - 1] !== M)

path.push(M);

//如果第1个 或者前面的都为null 修改起点坐标

len===3

&&(areaPath[1] = (draw.startX +(n+1)*draw.xPices + draw.offset).toFixed(0));

//如果前面一个不是结束标识符 区域图结束 如果第一个数据是null 则不进行下面的操作

if(areaPath[len - 1] !== seal&&n!==0){

areaPath=areaPath.concat([

areaPath[len - 2],

(draw.startY-draw.jianjuY).toFixed(0),

seal

]);

}

}else{

n !== 0 && path.push(L);

areaPath.push(L);

//如果前面的那个数据是null 把之前的那个L去掉

if(n > 0 && data[n - 1] == null){

path.pop();

//如果是第一个为null 不删除L

n!==1&&areaPath.pop();

}

var x = draw.startX + draw.offset + (n * draw.xPices),

y = draw.startY - data[n] * (draw.yPices / draw.feed);

if(isIE){

x = parseInt(x);

y = parseInt(y);

}

path.push(x);

path.push(y);

if(areaPath[len - 1] === seal){

areaPath = areaPath.concat([

M,

x,

parseInt(draw.startY-draw.jianjuY),

L,

x,

y

]);

}else{

areaPath.push(x);

areaPath.push(y);

}

//如果是最后一个点

if(n === l - 1){

areaPath.push(x);

areaPath.push(parseInt(draw.startY-draw.jianjuY));

}

//画点

self.baseDraw[o.dotType || 'circle'](self,{

x : x,

y : y,

r : 4,

fillColor : o.color

})

.attr({data:data[n],pos:x+'-'+(y-5)})

.on('mouseover',(function(o,x,y){

return function(){

if(self.currList.dot){

if(self.currList.dot[0] === this[0])

return;

self.currList.dot.setSize(0);

self.currList.line.setSize(1.5);

}

this.setSize(2);

line.setSize(2.5);

var pos = this.attr('pos').split('-');

self.showTooltip(o,pos[0],pos[1],this.attr('data'));

self.currList.dot = this;

self.currList.line = line;

}

})(o,x,y))

/*.on('mouseout',function(){

this.setSize(0);

line.setSize(1.5);

//self.hideTooltip()

})*/

.on('click',function(){areaGroup.toFront(); })

.css({zIndex:10,cursor:'pointer'})

.appendTo(areaGroup);

}

}

areaPath.push(seal)

self.baseDraw.path(self,{

border : 0,

isfill : true,

fillColor : o.color,

opacity : 0.5,

path : areaPath

})

.css({zIndex:5})

.appendTo(areaGroup);

line = self.baseDraw.path(self,{

border : 1.5,

borderColor : o.color,

isfill : false,

path : path

})

/*.on('mouseover',function(){

hasSVG

? this.attr({'stroke-width':2.5})

: (this[0].strokeWeight = 2.5);

})

.on('mouseout',function(){

hasSVG

? this.attr({'stroke-width':1.5})

: (this[0].strokeWeight = 1.5);

})*/

.on('click',function(){areaGroup.toFront(); })

.css({zIndex:-1})

.appendTo(areaGroup);

});

return this;

},

drawColumns : function(){

var self = this,

opts = this.opts,

draw = opts.draw,

chartData = opts.chartData,

dataLen = chartData.length,

//多个柱子之间的间距

columnSpace = 3,

//一个位置中 所有的间隔之和

columnPadding = columnSpace * dataLen + columnSpace,

//每个柱子的宽度

columnSize = self.opts.charts.panel==='x'

? Number(((draw.xPices - columnPadding) / dataLen).toFixed(0))

: Number(((draw.yPices - columnPadding) / dataLen).toFixed(0));

each(chartData, function(i,o){

var data = o.data,

id = 'chart' + i,

isX = opts.charts.panel==='x',

colGroup = self.group(id).appendTo(),

//每个点开始的位置

start = self.opts.charts.panel==='x'

? draw.startX + columnSpace + i*(columnSize+columnSpace)

: draw.startY + columnSpace + i*(columnSize+columnSpace)

self.mainGroup[id] = {chart:colGroup,show:true};

for(var j = 0,l=data.length; j < l ; j++){

if(data[j]===null) continue;

//如果是横盘子

if(isX){

var x = Number((start + j *draw.xPices ).toFixed(0)),

y = Number((draw.startY-draw.jianjuY).toFixed(0)),

height = Number((data[j] * (draw.yPices / draw.feed)-draw.jianjuY).toFixed(0)),

path = [

M,

x,

y,

L,

x,

y -height,

L,

x + columnSize,

y - height,

L,

x + columnSize,

y,

seal

];

var pos = [x+columnSize/2,data[j]>0?y-height:draw.startY-draw.jianjuY];

}else{

var x = Number((draw.startX+draw.jianjuX).toFixed(0)),

width = Number((data[j]*((draw.xPices / draw.feed))-draw.jianjuX).toFixed(0)),

y = Number((start - (j+1) *draw.yPices ).toFixed(0)),

path = [

M,

x,

y,

L,

x+ width,

y ,

L,

x + width,

y + columnSize,

L,

x ,

y+ columnSize,

seal

];

var pos = [draw.startX+draw.jianjuX+width/2,y];

}

self.baseDraw.path(self,{

border : 0,

isfill : true,

fillColor : o.color,

opacity : 1,

path : path

})

.attr({data:data[j],pos:pos[0]+'-'+pos[1]})

.css({zIndex:5,cursor:'pointer'})

.on('mouseover',(function(d){

return function(){

this.setOpacity(0.85);

var pos= this.attr('pos').split('-')

self.showTooltip(o,pos[0],pos[1],this.attr('data'));

}

})(data[j])

)

.on('mouseout',function(){

this.setOpacity(1);

})

.appendTo(colGroup);

}

});

return this;

},

drawPie : function(){

var self = this,

opts = this.opts,

area = opts.area,

rx = area.centerX,

ry = area.centerY,

inc = 0,

total = 0,

data = [],

cumulative = -0.25, // start at top;

circ = 2 * Math.PI,

radiu = mathMin(opts.charts.radius,mathMin(area.areaWidth/2,area.areaHeight/2)),

fraction,

half_fraction;

each(opts.chartData,function(i,o){

typeof o.data ==='object'

? (data.push((function(o){

var all =0;

for(var i in o)

all+=~~o[i]

return all

})(o.data)))

:data.push(mathAbs(o.data))

});

each(data,function(i,o){

total = total + o;

});

each(data,function(i,o){

var pieGroup = self.group('chart'+i).appendTo(),

s = inc/total*360,

e = (inc + o)/total*360,

name = opts.chartData[i].name,

size = calTextLen(name),

dot = angle(radiu,[rx,ry],s+(e-s)/2,2),

x = rx + (dot[0]-rx)/2 - size.w/2,

y = ry + (dot[1]-ry)/2 - size.h/2,

len = Math.sqrt((x-rx)*(x-rx)+(y-ry)*(y-ry)),

moveDisplacement = ((x-rx)*8/len)+','+((y-ry)*8/len);

inc = inc + o;

var value = Number(o);

fraction = total ? value / total : 0;

half_fraction = total ? (value / 2) / total : 0;

var start = cumulative * circ;

half_cumulative = cumulative + half_fraction;

cumulative += fraction;

var end = cumulative * circ;

self.baseDraw.pie(self,{

config : opts.chartData[i],

s : start,

e : end,

r : radiu,

innerR : 0

})

.css({zIndex:5,cursor:'pointer'})

.attr({move:moveDisplacement,pos:dot[0]+'-'+dot[1]})

.on('mouseover',function(){

this.setOpacity(0.85);

var pos = this.attr('pos').split('-');

self.showTooltip(opts.chartData[i],pos[0],pos[1],((e-s)/360*100).toFixed(0)+'%')

})

.on('mouseout',function(e){

var elem = e.toElement || e.relatedTarget;

//如果碰到里面的文本 或者是提示框 不消失

if(!elem||contains(this[0].parentNode,elem)||contains(self.tipC[0],elem))

return;

self.hideTooltip();

this.setOpacity(1);

})

.on('click',function(){

var m = this.attr('move')

if(m.indexOf('+')>0){

hasSVG

? this.attr({

transform: 'translate(0,0)'

})

: this.css({

left : '0px',

top : '0px'

})

this.attr({move:m.replace('+','')});

}else{

var s= m.split(',');

hasSVG

? this.attr({

transform: 'translate('+m+')'

})

: this.css({

left : s[0]+'px',

top : s[1]+'px'

})

this.attr({move:m+'+'});

}

})

.appendTo(pieGroup);

self.mainGroup['chart'+i] = {

chart : pieGroup,

show : true

};

self.baseDraw.span(self,{

x : x,

y : y,

fill : '#fff',

'text-anchor':'left'

})

.css({

fontFamily : 'Verdana,Arial,Helvetica,sans-serif',

fontSize : '12px',

position : 'absolute',

color : '#fff',

cursor : 'pointer',

zIndex : 10

})

.addText(name)

.appendTo(pieGroup);

});

},

drawPies : function(){

var self = this,

opts = this.opts,

area = opts.area,

rx = area.centerX,

ry = area.centerY,

total = 0,

data = [],

chartData = opts.chartData,

cumulative = -0.25, // start at top;

circ = 2 * Math.PI,

radiu = mathMin(opts.charts.radius,mathMin(area.areaWidth/2,area.areaHeight/2)),

fraction,

half_cumulative,

half_fraction;

each(chartData,function(i,o){

each(o.data,function(j,d){

data[j]

? data[j] +=mathAbs(d)

: data[j] =mathAbs(d)

});

});

//看有多少个数据来生成来生成内半径

var len = data.length,

innerSpace = radiu / 10;

Rpice = (radiu - innerSpace) / len;

each(data,function(i,d){

var inc = 0;

if(d===0) return;

each(chartData,function(j,o){

if(~~o.data[i]===0)return;

var outR = radiu - Rpice * i,

innerR = radiu - Rpice * (i + 1),

value = ~~o.data[i],

fraction = value / d;

half_fraction = (value/2)/d ,

start = cumulative * circ,

s = inc/d*360,

e = (inc + value)/d*360,

id = 'chart'+j,

piesGroup = self.mainGroup[id]?self.mainGroup[id].chart:self.group(id).appendTo();

!self.mainGroup[id]

&&(self.mainGroup[id] = {chart:piesGroup,show:true});

inc = inc + value;

varname = o.name,

size = calTextLen(name),

dot = angle(radiu,[rx,ry],s+(e-s)/2,2),

showDot = angle(radiu- Rpice * i,[rx,ry],s+(e-s)/2,2),

px = dot[0]>rx?1:-1,

py = dot[1]>ry?1:-1;

var x = rx + px*innerSpace + ((dot[0]-rx-px*innerSpace)/len)*(len-i-1)+((dot[0]-rx-px*innerSpace)/len)/2- size.w/2,

y = ry + py*innerSpace +((dot[1]-ry-py*innerSpace)/len)*(len-i-1)+((dot[1]-ry-py*innerSpace)/len)/2- size.h/2;

half_cumulative = cumulative + half_fraction,

cumulative += fraction,

end = cumulative * circ;

self.baseDraw.pie(self,{

config : o,

s : start,

e : end,

r : outR,

innerR : innerR

})

.attr({m : i+'-'+j,data:((e-s)/360*100).toFixed(0)+'%',pos:showDot[0]+'-'+showDot[1]})

.css({zIndex:5,cursor:'pointer'})

.on('mouseover',function(){

this.setOpacity(0.85);

var pos = this.attr('pos').split('-');

self.showTooltip(o,pos[0],pos[1],this.attr('data'))

})

.on('mouseout',function(e){

var elem = e.toElement || e.relatedTarget;

if(!elem||elem.getAttribute('m')===this[0].getAttribute('m'))

return;

this.setOpacity(1);

})

.appendTo(piesGroup);

self.baseDraw.span(self,{

x : x,

y : y,

fill : '#fff',

'text-anchor':'left'

})

.attr({m : i+'-'+j})

.css({

fontFamily : 'Verdana,Arial,Helvetica,sans-serif',

fontSize : '12px',

position : 'absolute',

color : '#fff',

cursor : 'pointer',

zIndex : 10

})

.addText(name)

.appendTo(piesGroup);

});

});

},

drawSegment : function(){

var self = this,

opts = this.opts,

draw = opts.draw,

chartData = opts.chartData,

typeIsX = opts.charts.panel==='x',

columnPad = 5,

prev = [],

columnSize = ~~(typeIsX?draw.xPices:draw.yPices) - columnPad * 2;

each(chartData,function(i,c){

if(i in self.hideList)

return;

var id = 'chart' + i,

segmentGroup = self.mainGroup[id]?self.mainGroup[id].chart:self.group(id).appendTo();

self.mainGroup[id] = {chart : segmentGroup,show : true};

each(c.data,function(j,d){

if(d===null||d===0)

return;

if(typeIsX){

var start = draw.startX + columnPad,

x = ~~(start + j*draw.xPices).toFixed(0),

y = ~~(draw.startY-(prev[j]?prev[j]:0)).toFixed(0),

size = ~~(d*draw.yPices / draw.feed ).toFixed(0),

path = [

M,

x,

y,

L,

x,

y - size,

L,

x + columnSize,

y - size,

L,

x + columnSize,

y,

seal

];

var pos = [x + columnSize/2,y-size];

}else{

var start = draw.startY - columnPad,

x = ~~(draw.startX+(prev[j]?prev[j]:0)).toFixed(0) ,

y = ~~(start- j*draw.yPices).toFixed(0),

size = ~~(d*draw.xPices / draw.feed ).toFixed(0),

path = [

M,

x,

y,

L,

x + size,

y ,

L,

x + size,

y - columnSize,

L,

x ,

y - columnSize,

seal

];

var pos = [x+size/2,y - columnSize];

}

self.baseDraw.path(self,{

border : 0,

isfill : true,

fillColor : c.color,

opacity : 1,

path : path

})

.attr({data:d,pos:pos[0]+'-'+pos[1]})

.on('mouseover',function(){

this.setOpacity(0.85);

var pos = this.attr('pos').split('-');

self.showTooltip(chartData[i],pos[0],pos[1],this.attr('data'))

})

.on('mouseout',function(){

this.setOpacity(1);

})

.css({zIndex:5,cursor:'pointer',left:'0px',top:'0px'})

.appendTo(segmentGroup);

prev[j]

? prev[j] = prev[j] + size

: prev[j] = size;

});

});

},

baseDraw : {

rect : function(o,config){

return o.createElement('rect')

.attr({

rx : config.arc*30 || 5,

ry : config.arc*30 || 5,

width : config.width || 50,

height : config.height || 50,

fill : config.fill || '#fff',

'fill-opacity' : config.opacity || 0.85,

'stroke-width' : config.border || 2,

stroke : config.borderColor || '#606060',

transform : 'translate('+(config.left||0)+','+(config.top||0)+')'

});

},

text : function(o,config){

return o.createElement('text')

.attr(config);

},

span : function(o,config,v){

return o.createElement('text')

.attr(config)

.attr({

y : config.y+(v||15)

});

},

path : function(o,config){

var set = {};

set['stroke-width'] = config.border;

set.stroke = config.borderColor || '#C0C0C0';

set.fill = config.isfill?config.fillColor:'none';

set.d = config.path;

config.opacity

&&(set['fill-opacity'] = config.opacity);

return o.createElement('path')

.attr(set);

},

circle : function(o,config){

var set = {};

set.cx = config.x;

set.cy = config.y;

set['stroke-width'] = 0;

set.stroke = config.borderColor || '#C0C0C0';

set.r = config.r;

set.fill = config.fillColor;

return o.createElement('circle')

.attr(set);

},

square : function(o,config){

var x = config.x,

y = config.y,

r = config.r,

color= config.fillColor,

len = r,

path = [

M,

(x-len).toFixed(0),

(y-len).toFixed(0),

L,

(x+len).toFixed(0),

(y-len).toFixed(0),

(x+len).toFixed(0),

(y+len).toFixed(0),

(x-len).toFixed(0),

(y+len).toFixed(0),

seal

];

return o.baseDraw.path(o,{

border : 1,

borderColor : color,

isfill : true,

fillColor : color,

path : path

});

},

triangle : function(o,config){

var x = config.x,

y = config.y,

r = config.r+0.1,

color = config.fillColor,

path = [

M,

x.toFixed(0),

(y-1.33*r).toFixed(0),

L,

(x+r).toFixed(0),

(y+0.67*r).toFixed(0),

(x-r).toFixed(0),

(y+0.67*r).toFixed(0),

seal

];

return o.baseDraw.path(o,{

border : 1,

borderColor : color,

isfill : true,

fillColor : color,

path : path

});

},

diamond : function(o,config){

var x = config.x,

y = config.y,

r = 1.35*config.r,

color = config.fillColor,

path = [

M,

x.toFixed(0),

(y-r).toFixed(0),

L,

(x+r).toFixed(0),

y.toFixed(0),

x.toFixed(0),

(y+r).toFixed(0),

(x-r).toFixed(0),

y.toFixed(0),

seal

];

return o.baseDraw.path(o,{

border : 1,

borderColor : color,

isfill : true,

fillColor : color,

path : path

});

},

pie : function(o,config){

//config,s,e,r,index

var opts = o.opts,

s = config.s,

r = config.r,

e = config.e - 0.000001,

id = 'chart'+config.index,

area = opts.area,

rx = area.centerX,

ry = area.centerY,

cosStart = mathCos(s),

sinStart = mathSin(s),

cosEnd = mathCos(e),

sinEnd = mathSin(e),

color = config.config.color,

innerR = config.innerR,

longArc = e - s < Math.PI ? 0 : 1,

path = [

M,

rx + r * cosStart,

ry + r * sinStart,

'A',

r,

r,

0,

longArc,

1,

rx + r * cosEnd,

ry + r * sinEnd,

L,

rx + innerR * cosEnd,

ry + innerR * sinEnd,

'A', // arcTo

innerR, // x radius

innerR, // y radius

0, // slanting

longArc, // long or short arc

0, // clockwise

rx + innerR * cosStart,

ry + innerR * sinStart,

'Z'

];

return o.baseDraw.path(o,{

border : 1,

border : '#fff',

isfill : true,

fillColor : color,

opacity : 1,

path : path

})

}

}

};

//---------------------------------------------------------------------------------------------------

//如果是vml 修改smipleChart.prototype中的一些方法

!hasSVG

&&extend(smipleChart.prototype.baseDraw,{

rect : function(o,config){

var attr = {},

css = {};

attr.arcsize = config.arc || 0.2 +'';

if(config.fill==='none'){

attr.filled = 'f'

}else{

attr.filled = 't';

attr.fillcolor = config.fill || '#fff';

}

attr.strokeWeight = config.border || 2;

attr.strokeColor = config.borderColor || '#606060';

css.width = config.width || 50 +'px';

css.height = config.height || 50 +'px';

css.zIndex = 10;

css.left = config.left||0+'px';

css.top = config.top ||0+'px';

return o.createElement('roundrect')

.attr(attr)

.css(css);

},

text : function(o,config){

return o.createElement('TextBox')

.attr({inset : "2px,2px,2px,2px" })

.css({zIndex:200})

},

span : function(o,config){

return o.createElement('span').

css({

position:'absolute',

left : config.x+'px',

top : config.y+'px'

})

},

path : function(o,config){

var attr = {},

width = o.width,

height = o.height,

css = {

width : width+'px',

height : height+'px'

};

if(config.border===0){

attr.Stroked = 'f';

attr.strokeWeight =0;

}else{

attr.strokeWeight = config.border||1 ;

}

attr.strokeColor = config.borderColor || "#C0C0C0";

attr.filled = config.isfill?'t':'f';

attr.filled==='t'

&&(attr.fillcolor=config.fillColor||"#C0C0C0");

attr.coordsize = width+','+height;

attr.path = config.path;

var elem = o.createElement()

.attr(attr)

.css(css);

if(config.opacity){

var fill = o.createElement('fill')

.attr({

type : 'fill',

color : config.fillColor||"#C0C0C0",

opacity : config.opacity

})

.appendTo(elem);

//那这个对象的一个属性引用设置透明的元素 以后会用到

elem.opacity = fill[0];

}

return elem;

},

circle : function(o,config){

var width = o.width,

height = o.height,

attr = {

strokeWeight : 1,

coordsize : width+','+height,

filled : 't'

},

css ={

width : width+'px',

height : height+'px'

}

x = config.x,

y = config.y,

r = config.r;

attr.strokeColor=attr.fillcolor = config.fillColor

attr.path =[

'wa', // clockwisearcto

x - r, // left

y - r, // top

x + r, // right

y + r, // bottom

x + r, // start x

y, // start y

x + r, // end x

y, // end y

'e' // close

];

return o.createElement()

.attr(attr)

.css(css)

},

pie : function(o,config){

////config,s,e,r,index

var opts = o.opts,

area = opts.area,

r = config.r,

rx = area.centerX,

ry = area.centerY,

innerR= config.innerR||0,

sDot = angle(r,[rx,ry],s,2),

eDot = angle(r,[rx,ry],e,2),

color = config.config.color,

s = config.s,

e = config.e,

e = e - s == 2 * Math.PI ? e - 0.001 : e,

cosStart = mathCos(s),

sinStart = mathSin(s),

cosEnd = mathCos(e),

sinEnd = mathSin(e),

path = [

'wa', // clockwisearcto

(rx - r).toFixed(0), // left

(ry - r).toFixed(0), // top

(rx + r).toFixed(0), // right

(ry + r).toFixed(0), // bottom

(rx + r * cosStart).toFixed(0), // start x

(ry + r * sinStart).toFixed(0), // start y

(rx + r * cosEnd).toFixed(0), // end x

(ry + r * sinEnd).toFixed(0), // end y

'at', // clockwisearcto

(rx - innerR).toFixed(0), // left

(ry - innerR).toFixed(0), // top

(rx + innerR).toFixed(0), // right

(ry + innerR).toFixed(0), // bottom

(rx + innerR * cosEnd).toFixed(0), // start x

(ry + innerR * sinEnd).toFixed(0), // start y

(rx + innerR * cosStart).toFixed(0), // end x

(ry + innerR * sinStart).toFixed(0), // end y

'x', // finish path

'e' // close

];

return o.baseDraw.path(o,{

border : 1,

border : '#fff',

isfill : true,

fillColor : color,

opacity : 1,

path : path

})

}

});

//---------------------------------------------------------------------------------------------------

})(document);

window.onload = function(){

var t = new Date().getTime();

var config = {

charts : {

type : 'line',

radius : 150,

panel : 'x',

style: {

fontFamily: '"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif', // default font

fontSize: '12px'

}

},

title : {

text: '线性图表',

y: 10,

style: {

color: 'black',

fontSize: '16px'

}

},

subTitle : {

text: '线性图表副标题',

y: 35,

style: {

color: '#111',

fontSize: '12px'

}

},

legend : {

enable : true,

//type : 'lateral', // lateral 横向 或 lengthwise 纵向

type : 'lateral',

pos : [10,10],

style:{

fontFamily : '"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif', // default font

fontSize : '12px',

magin : '0px'

}

},

yUnit : {

text : '线性图表侧标题',

x : 20,

style : {

color : '#111',

fontSize : '12px'

}

},

xUnit : {

units: [

'一月',

'二月',

'三月',

'四月',

'五月',

'六月',

'七月',

'八月',

'九月',

'十月',

'十一月',

'十二月'

]

},

chartData : [

{

name : 'xcv',

color : '#4572A7',

dotType : 'square',

//data : [11,12,13,15,16,18,17,14,10]

//[1,2,3,5,6,8,7,4,10]

data: [44,-12,-78,100,-13,-4,-26,34]

}, {

name: 'frfr',

color: '#AA4643',

dotType : 'triangle',

data: [-44,12,78,-100,13,4,-56,-34]

}, {

name: 'AAAAA',

color: '#89A54E',

dotType : 'diamond',

data: [null,78,83,null,22,-78,2,44,78]

}, {

name: 'BBBB',

color: '#80699B',

data: [null, 58, 35, null, 52, 47, 26, -55, 39, 123,15,66]

}

]

};

new smipleChart($$('line'),config);

config.charts.type ='area';

config.title.text ='区域图表'

config.subTitle.text='区域图表副标题'

config.yUnit.text ='区域图表侧标题'

config.chartData = [

{

name : 'xcv',

color : '#4572A7',

//data : [0,3,4,5,6,7,8,9,10,11]

data : [11,12,13,14,15,16,-17,18,19,0]

}, {

name: 'frfr',

color: '#AA4643',

data: [44,12,78,100,13,44,56,34]

}, {

name: 'AAAAA',

color: '#89A54E',

data: [null,101,83,null,22,78,88,44,78]

}, {

name: 'BBBB',

color: '#80699B',

data: [null, 58, 35, null, 52, 47, 26, 55, 39, 123,15,66]

}

]

new smipleChart($$('area'),config);

config.title.text ='柱状图表'

config.subTitle.text='柱状图表副标题'

config.yUnit.text ='柱状图表侧标题'

config.charts.type ='columns';

config.chartData =[

{

name : 'xcv',

color : '#4572A7',

//data : [2,3,4,5,6,7,8,9,10,11]

data : [-0.01,-0.62,0,0.55,null,0.78,-0.63,-0.82,null,null,0.33]

}, {

name: 'frfr',

color: '#AA4643',

data: [-0.22,0.82,0.55,1.32,0.33,0.95,null,1,0.65,null,0.78]

}, {

name: 'AAAAA',

color: '#89A54E',

data: [null,0.62,0.34,null,0.63,0,-0.23,-1,0.62,0.45,null,-0.56]

}

]

new smipleChart($$('zhu'),config);

config.charts.panel='y'

new smipleChart($$('zhu1'),config);

config.charts.type ='pie';

config.title.text ='饼图图表'

config.subTitle.text='饼图图表副标题'

config.yUnit.text =''

config.legend.type='lengthwise';

config.chartData =[

{

name : 'aaa',

color : '#4572A7',

data : [433,123,null,66]

}, {

name: 'bbb',

color: '#AA4643',

data: [45,33,33,411]

}, {

name: 'ccc',

color: '#89A54E',

data: [55,null,75,233]

}, {

name: 'ddd',

color: '#80699B',

data: [63,null,100,333]

}

]

config.legend.pos= [680,30]

new smipleChart($$('pie'),config);

config.charts.type ='pies';

config.title.text ='多层饼图图表'

config.subTitle.text='多层饼图图表副标题'

config.legend.type='lateral';

config.legend.pos= [290,400]

new smipleChart($$('pies'),config);

config.chartData =[

{

name : 'xcv',

color : '#4572A7',

data : [111,222,333,null,444,555,56,57,84]

}, {

name: 'frfr',

color: '#AA4643',

data: [845,666,100,null,666,677,56,88,633,55,555]

}, {

name: 'AAAAA',

color: '#89A54E',

data: [555,162,75,null,364,0,637,112,163,615]

}

]

config.charts.type ='line';

config.legend.pos= [10,10]

//

config.yUnit.lineNum = 10;

config.charts.panel = 'x';

config.title.text ='分段图表'

config.subTitle.text='分段图表副标题'

config.yUnit.text ='分段图表侧标题'

config.charts.type ='segment';

new smipleChart($$('segmentx'),config);

config.charts.panel = 'y';

new smipleChart($$('segmenty'),config);

config.yUnit.lineNum = 2;

config.title.text ='比较小的'

config.subTitle.text='只设置了2条线'

config.yUnit.text ='小测标题';

new smipleChart($$('vv'),config);

//alert(new Date().getTime()-t)

}

</script>

</body>

</html>

js浮点精度问题 不好解决 求助。。。。。。。。。

水平有限 难免问题多多 望赐教。。。。。。。

【javascript使用smipleChart实现简单图表】相关文章:

javascript实现表格增删改操作实例详解

javascript基于DOM实现权限选择实例分析

JavaScript实现列表分页功能特效

Javascript调用XML制作连动下拉列表框

JavaScript实现简单的数字倒计时

JavaScript实现带标题的图片轮播特效

JavaScript使用技巧精选

javascript下使用Promise封装FileReader

javascript实现链接单选效果

javascript自定义右键弹出菜单实现方法

精品推荐
分类导航