javascript使用smipleChart实现简单图表
支持线性图区域图柱状图饼图
支持多浏览器
用到的是svg vml
<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <htmlxmlns="http://www.w3.org/1999/xhtml"> <head> <metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/> <title>smipleChart</title> <styletype="text/css"> .cc{ height:450px;width:800px;border:1pxsolid#999;position:relative;margin:20px; } </style> </head> <body> <divid='t'></div> <divid='t1'></div> <divid='line'class="cc"></div> <divid='area'class="cc"></div> <divid='zhu'class="cc"></div> <divid='zhu1'class="cc"style="height:600px;"></div> <divid='segmentx'class="cc"></div> <divid='segmenty'class="cc"></div> <divid='pie'class="cc"></div> <divid='pies'class="cc"></div> <divid='vv'class="cc"style='height:300px;width:520px;'></div> <scripttype="text/javascript"> (function(doc,undefined){ varwin =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){ returndocument.getElementById(Id); }; win.extend=function(){ vartarget=arguments[0]||{},i=1,length=arguments.length,deep=true,options; if(typeoftarget==="boolean"){ deep=target; target=arguments[1]||{}; i=2; } if(typeoftarget!=="object"&&Object.prototype.toString.call(target)!="[objectFunction]") target={}; for(;i<length;i++){ if((options=arguments[i])!=null) for(varnameinoptions){ varsrc=target[name],copy=options[name]; if(target===copy) continue; if(deep&©&&typeofcopy==="object"&&!copy.nodeType){ target[name]=arguments.callee(deep,src||(copy.length!=null?[]:{}),copy); } elseif(copy!==undefined) target[name]=copy; } } returntarget; }; win.each= function(object,callback,args){ varname,i=0,length=object.length; if(args){ args=Array.prototype.slice.call(arguments).slice(2); if(length===undefined){ for(nameinobject) 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(nameinobject) if(callback.call(object[name],name,object[name])===false) break; }else for(varvalue=object[0]; i<length&&callback.call(value,i,value)!==false;value=object[++i]){} } returnobject; }; win.contains=function(p,c){ if(!p||!c)returnfalse; if(p===c)returntrue; returnisIE ?p.contains(c) :p.compareDocumentPosition(c)==20 ?true :false; }; //--------------------------------------------------------------- functionprocessPoint(x){ returnisIE?~~x.toFixed(0):~~x.toFixed(0)+0.5; }; functioncalTextLen(txt,cssStr){ varspan=doc.createElement('span'); if(cssStr){ typeofcssStr==='string' ?span.style.cssText=cssStr :extend(span.style,cssStr); }else{ extend(span.style,{ fontSiz :'12px', fontFamily:'"LucidaGrande","LucidaSansUnicode",Verdana,Arial,Helvetica,sans-serif' }); } span.innerHTML=txt||''; span.style.visibility='hidden'; doc.body.appendChild(span); varwidth =span.offsetWidth, height=span.offsetHeight; doc.body.removeChild(span); return{w:width,h:height}; }; functionangle(r,center,o,jingdu){ varhudu=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)]; } functionxx(a,b,lineNum){ vart =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; }); }elseif(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; returnfalse; } }); varbj =(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; //看看还剩几条线没有画 varnum=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}; } //--------------------------------------------------------------------------------------------------------------- //对svgvml元素的一些创建修改属性样式删除== 一些的操作 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; returnthis; }, attr: function(hash,val){ varelem =this.element, key, value; if(typeofhash==='string'){ if(val===undefined){ returnelem.getAttribute(hash); }else{ elem.setAttribute(hash,val); returnthis; } }else{ for(keyinhash){ value=hash[key]; if(key===path){ value&&value.join &&(value=value.join('')); /(NaN| |^$)/.test(value) &&(value='M00'); } elem.setAttribute(key,value) } } returnthis; }, css: function(hash){ for(varkeyinhash){ isIE&&key=="opacity" ?this[0].style['filter']="alpha(opacity="+hash[key]*100+")" :this[0].style[key]=hash[key]; } returnthis; }, on:function(eventName,handler){ varself=this; /*this.element.addEventListener(eventName,function(){ handler.call(self) },false);*/ this.element['on'+eventName]=function(e){ e=e||win.event; handler.call(self,e); } returnthis; }, appendTo: function(parent){ if(parent){ parent.element ?parent.element.appendChild(this.element) :parent.appendChild(this.element) }else{ this.graphic.container.appendChild(this.element); } returnthis; }, addText:function(str){ varelem=this.element; if(elem.nodeName==='text'){ elem.appendChild(doc.createTextNode(str+'')); } returnthis; }, setOpacity:function(v){ this.attr('fill-opacity',v); returnthis; }, setSize:function(v){ this[0].nodeName==='circle' ?this.attr('r',4+(v===0?0:2)) :this.attr({'stroke-width':v}); returnthis; }, toFront:function(){ this[0].parentNode.appendChild(this[0]); returnthis; }, show: function(){ this[0].style.display='block'; returnthis; }, hide: function(){ this[0].style.display='none'; returnthis; }, destroy:function(){ //销毁节点...................... varnode=this[0]||this; node.onmouseover=node.onmouseout=node.onclick=null; node.parentNode &&node.parentNode.removeChild(node); returnthis; } }; //--------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------- //如果是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){ varname=nodeName||'shape'; this.element=this[0]=(name==='div'||name==='span') ?doc.createElement(name) :doc.createElement('<vml:'+name+'class="vml">'); this.graphic=graphic; returnthis; }, /*on:function(eventName,handler){ varself=this; this.element.attachEvent("on"+eventName,function(){ handler.call(self); }); returnthis; },*/ addText:function(txt){ this[0].innerHTML=txt||''; returnthis; }, setSize:function(v){ this[0].strokeWeight=v; returnthis; }, setOpacity:function(v){ this.opacity.opacity=v; returnthis; } }); } //--------------------------------------------------------------------------------------------------- //画图类 //------------------------------------------------------------ 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:'"LucidaGrande","LucidaSansUnicode",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) varself =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 ?newvector().$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) :newvector().$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'; varc =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(){ varopts =this.opts, self =this, type =opts.charts.type; this.container=this.container .on('mouseout',function(e){ varelem=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); //画色块条 vartype={ 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){ returnnewvector().$c(this,nodeName); }, group:function(name){ returnthis.createElement(hasSVG?'g':'div').attr('mark',name); }, getDrawArea:function(){ varopts =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; returnthis; }, drawTitle:function(){ varopts =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){ vartext=title.text; if(text){ varelem=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)') } } }); returnthis; }, //画盘子 比较麻烦 drawPanel:function(type){ var opts=this.opts, self=this, area=opts.area, chartsType=opts.charts.type, isSegment =chartsType==='segment', //盘子的类型是横盘子还是纵盘子 type=opts.charts.panel||'x'; //底板 vardrawAreaWidth =area.areaWidth, drawAreaHeight=area.areaHeight, //原点的坐标 startX=area.startX, startY=area.startY; varallData =[], 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){returna-b}); //求出最大值最小值 maxValue=allData[allData.length-1]; each(allData,function(i,o){ if(o!==null){ minValue=o; returnfalse; } }); //主盘子容器 varpanel=this.group('panel').appendTo(); varresult=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; //--------------------------------画横向的点和文字--------------------------------------------------------- vary=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); varspan=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) }); varxPices=drawAreaWidth/lineNum; for(vari=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那部分的值 varjianju=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轴的每份有多少 } returnthis; }, 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 所以这里的父不一洋 varp=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); returnthis; }, showTooltip:function(obj,x,y,data){ /*vartxt =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); vartxt =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{ varmove=function(t,b,c,d){ returnc*(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++; varx=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){ varself =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){ varg=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]=''; varmainGroup=self.mainGroup; for(varnameinmainGroup){ varparent=mainGroup[name].chart, nodes =parent[0].childNodes, len =nodes.length; //销毁图上面画的东西 for(vari=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){ deleteself.hideList[i]; varmainGroup=self.mainGroup; for(varnameinmainGroup){ varparent=mainGroup[name].chart, nodes =parent[0].childNodes, len =nodes.length; for(vari=len-1;i>=0;i--){ vector.prototype.destroy.call(nodes[i]) } } self.drawSegment(); } } }, arr=[]; type=type||'lateral'; varlegendPanel=self.group('Legend') .appendTo(); if(type==='lateral'){ //如果是横着的 vartop =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; varw=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{ vartop =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); varh=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); } returnthis; }, drawLine :function(){ varself=this, opts=this.opts, draw=opts.draw; each(opts.chartData,function(i,o){ varid='chart'+i, lineGroup=self.group(id) .appendTo(); self.mainGroup[id]={ chart:lineGroup, show :true }; varpath=[M], data=o.data, line; for(vari=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的位置 varx=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); //画点 vardotType=o.dotType||'circle'; self.baseDraw[dotType](self,{ x:x,