首页 / 脚本样式 / JavaScript / javascript使用smipleChart实现简单图表
支持 线性图 区域图 柱状图 饼图 支持多浏览器 用到的是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);
收藏该网址