时间:2021-07-01 10:21:17 帮助过:13人阅读
支持 线性图 区域图 柱状图 饼图
支持多浏览器
用到的是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' class="cc"></div>
<div id='area' class="cc"></div>
<div id='zhu' class="cc"></div>
<div id='zhu1' class="cc" style="height:600px;"></div>
<div id='segmentx' class="cc"></div>
<div id='segmenty' class="cc"></div>
<div id='pie' class="cc"></div>
<div id='pies' class="cc"></div>
<div id='vv' class="cc" style='height:300px; width:520px;'></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+' class="vml">');
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){
var opts = 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'){
//横坐标单位间隔
var xPices = 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{
//横坐标单位间隔
var yPices = 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',