smipleChart 简单图标类 javascript(支持 线性图 区域图 柱状图 饼图 )

    技术2022-07-04  129

    <!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='pie' class="cc"></div><div id='vv' class="cc" style='height:300px; width:520px;'></div><script type="text/javascript">(function(doc,undefined){ var win = this,  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;   };   //--------------------------------------------------------------- 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 = 10000;  var 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;   }  });   //a 是最小的   //b是最大 的  a = (a*t-mathAbs((a%v)*t))/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){   //让图比较靠中间   /*while(num!==0){    num%2===0     ? a = (a*t-v*t)/t     : b = (b*t+v*t)/t;    num--;    }*/    //坐标比较整数化    if(a!=0&&num!=0){    while(a!=0&&num!=0){     a = (a*t-v*t)/t;     num--;     if((a*t-v*num*t)/10000>0&&a===0)     break;    }   }      if(num!=0){    while(num!==0){    b = (b*t+v*t)/t    num--;     }   }        }else{   //让图比较靠中间   /*while(num!==0){    num%2===0     ? b = (b*t+v*t)/t     : a = (a*t-v*t)/t    num--;    }*/   //坐标比较整数化    if(b<0&&num!=0){    while(b!=0&&num!=0){     b = (b*t+v*t)/t;     num--;     if((b*t+v*num*t)/t<0&&a===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(){}; win.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){   var str = '';   for(var key in hash){    if(isIE && key == "opacity"){     this.element.style['filter'] = "alpha(opacity="+ hash[key] * 100+")";    }else{     this.element.style[key] = hash[key];    }   }   return this;  },  on:  function(eventName, handler){   var self = this;   this.element.addEventListener(eventName,function(){    handler.call(self)   },false);   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.toString() || ' '));   }   return this;  },  setOpacity : function(v){   this.attr('fill-opacity',v)  },  toFront: function() {   this.element.parentNode.appendChild(this.element)   return this;  },    show: function(){   this.element.style.display = 'block';   return this;  },  hide: function(){   this.element.style.display = 'none';   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){    var elem = this.element;    elem.innerHTML = txt || '';    return this;   },   setOpacity : function(v){    this.opacity.opacity=v;   }    }); }//---------------------------------------------------------------------------------------------------

     

     

     

    //画图类 //------------------------------------------------------------ win.smipleChart = function(){  this.init.apply(this,arguments); }; 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,width,height){   this.width  = width || container.offsetWidth;   this.height = height || container.offsetHeight;    this.mainGroup = {};         //svg 里面画图 必须有一个svg标签 vml就用div了   this.container = hasSVG     ? new vector().$c(1,'svg')     .attr({      xmlns   : 'http://www.w3.org/2000/svg',      version : '1.1'     })     .css({fontSize : '12px'})     .appendTo(container).element    : new vector().$c(1,'div')     .css({      fontSize : '12px',      width    : this.width +'px',      height   : this.height+'px'     })     .appendTo(container).element;   var c =  extend(true,{},this.options)   var ops   = this.ops = extend(true,c,options),    style = extend(ops.charts.style,{     width  : this.width,     height : this.height    });             //计算绘画盘子的时候需要的一些参数   this.getDrawArea()    .createTooltip()         //创建提示信息的框框    .drawTitle()             //画标题                //画盘子       if('xxline,area,pie'.indexOf(ops.charts.type)>=0){    ops.charts.panel = 'x';   }      if(ops.charts.type!='pie'){    this.drawPanel();   }      this.drawLegend(ops.legend.type);  //画色块条

       var type = {    line    : 'drawLine',    area    : 'drawArea',    columns : 'drawColumns',    pie     : 'drawPie'   }[ops.charts.type];   this[type]();     },  createElement : function(nodeName){   return new vector().$c(this,nodeName);  },  group: function(name){   return this.createElement(isIE?'div':'g').attr('mark',name);  },    getDrawArea : function(){   var ops      = this.ops,    width    = this.width,    height   = this.height,    title    = ops.title,    subTitle = ops.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;      ops.area = area;         return this;

      },  drawTitle : function(){      var opts   = this.ops,    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',{       '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.ops,    self = this,    area = opts.area,    //盘子的类型 是横盘子 还是纵盘子    type = opts.charts.panel || 'x';      // 底板   var drawAreaWidth = area.areaWidth,    drawAreaHeight = area.areaHeight,     //原点的坐标    startX = area.startX,    startY = area.startY;

       var allData  = [],    minValue = 0,    maxValue = 10,    lineNum  = mathMax(opts.yUnit.lineNum,2),    min      = opts.yUnit.min,    staff;      //组合所有的数据   each(opts.chartData,function(i,o){    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){     minValue = o;     return false;    }       });              //主盘子容器   this.panel = this.group('panel').appendTo();        var dd = xx(minValue,maxValue,lineNum),    min = dd.min,    max = dd.max,    f = dd.stf;      //表示画的是横坐标   if(type.toLowerCase()==='x'){    //横坐标单位间隔    var xPices = drawAreaWidth / opts.xUnit.units.length,     //单位间隔的中心点     offset = xPices / 2,          yPices = drawAreaHeight / lineNum;

        //--------------------------------画横向的点和文字---------------------------------------------------------       each(opts.xUnit.units,function(i,d){     self.baseDraw('path',{      border      : 1,      borderColor : '#C0C0C0',      isfill      : false,      path        : [       M,        processPoint(startX + (i * xPices)),        processPoint(startY),        L,       processPoint(startX + (i*xPices)),       processPoint(startY + 5)      ]     }).     appendTo(self.panel);     var y = hasSVG?5:10,      span = self.baseDraw('span',{       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(self.panel)      .element;          //vml没有x y的概念  所以要简单span宽度的一半  以后用span都需要减掉     !hasSVG      span.style.left = parseInt(span.style.left) - span.offsetWidth/2+'px';          });//--------------------------------画纵向的点和文字-----------------------------------------------------------------------        for(i=0;i<=lineNum;i++){     self.baseDraw('path',{      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(self.panel);          var span = self.baseDraw('span',{      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*1000+(i*1000*f/1000)*1000)/1000+'')     .appendTo(self.panel)     .element;

         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);          var x  = hasSVG?25:70,     vv = hasSVG?0:5;        each(opts.xUnit.units,function(i,d){                self.baseDraw('path',{      border      : 1,      borderColor : '#C0C0C0',      isfill      : false,      path        : [       M,       processPoint(startX-5),       processPoint(startY-i * yPices),       L,       processPoint(startX),       processPoint(startY-i * yPices),      ]     })     .appendTo(self.panel);     var span = self.baseDraw('span',{      x   : startX - x,      y   : startY -i * yPices-offset-calTextLen(d).h/2+vv,      'text-anchor':'middle'     })     .css({       fontFamily:'Verdana,Arial,Helvetica,sans-serif',       fontSize:'12px',       width   : '60px',       textAlign:'right'     })     .addText(d)     .appendTo(self.panel)         });            var xPices = drawAreaWidth / lineNum;        for(var i=0;i<=lineNum;i++){     self.baseDraw('path',{      border      : 1,      borderColor : '#C0C0C0',      isfill      : false,      path        : [       M,        processPoint(startX + (i * xPices)),        processPoint(startY),        L,        processPoint(startX + (i*xPices)),       processPoint(startY - drawAreaHeight)      ]     }).     appendTo(self.panel);          var span = self.baseDraw('span',{      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(self.panel)     .element;        }       }

    //-----------------------------------------------------------------------------------------------------     //在画区域图的时候还需要起点的位置啊    //因为坐标很可能是负数 而且也能不是从0开始的 所以+上jianju    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 单分中心点位置偏移量     jianju : jianju*yPices/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',{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',{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||'#606060';       }

       this.tipText.nodeValue = txt || '';  },  hideTooltip: function(){   this.tipC.hide();  },   

      drawLegend : function(type,redraw){   var self = this,    ops  = this.ops,    //颜色块的大小    t_width = 20,    t_height = 20,    //块之间的距离    t_space = 5,         datas = ops.chartData,    len = datas.length,    css = ops.legend.style,

        //最大长度 如果是纵着的 需要最大的长度    maxWidth  = 10,    maxHeight = 30,    //这个东西的位置    orig_pos = ops.legend.pos?ops.legend.pos:[2,2],        //显示隐藏组的函数    handle = function(i){      var g = self.mainGroup['chart'+i];      if(g.show){       g.chart.hide();       g.show = false;       hasSVG        ? this.attr({fill:'#ccc'})        : this[0].style.color = '#ccc'      }else{       g.chart.show();       g.show = true;       hasSVG        ? this.attr({fill:'#000'})        : this[0].style.color = '#000'      }    },        arr = [];       type = type ||'lateral';    var legendPanel = self.group('Legend')    //.css({position:'relative'})    .appendTo();   if(type==='lateral'){    //如果是横着的    var top  = orig_pos[0] + 5,     th   = hasSVG?0:3,     left = orig_pos[1] + 5;     each(datas, function(i,d){               left = i===0 ? left : t_space+left;     //计算所有left的位置     self.baseDraw('rect',{      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',{      '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',{      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[0] + 5,     th   = hasSVG?0:3,     left = orig_pos[1] + 5;    each(datas, function(i,d){     top = i===0 ? top : t_space + top;     self.baseDraw('rect',{      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',{      'text-anchor':'left',      x : left+t_width+2+t_space,      y : top+th     })     .css(extend(css,{cursor:'pointer'}))     .addText(d.name)     .on('click',function(){handle.call(this,i)})     .appendTo(legendPanel);      top = top + h+ t_space;     maxWidth = Math.max(maxWidth,calTextLen(d.name,css).w);    });     this.baseDraw('rect',{      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.ops,    vmlWidth  = this.width,    vmlHeight = this.height    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; i < data.length; 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);      //画点      self.baseDraw('circle',{       x : x,            y : y,       r : 4,       fillColor : o.color      })      .attr({data:data[i]})      .css({zIndex:10,cursor:'pointer'})      .on('mouseover',(function(o,x,y){       return function(){        hasSVG         ? (this[0].setAttribute('r','5'),line.attr({'stroke-width':2.5}))         : (this[0].strokeWeight = 3,line[0].strokeWeight = 2.5);                self.showTooltip(o,x,y,this.attr('data'));       }                        })(o,x,y))      .on('mouseout',function(){       hasSVG        ? (this[0].setAttribute('r','4'),line.attr({'stroke-width':1.5}))        : (this[0].strokeWeight = 1,line[0].strokeWeight = 1.5);       self.hideTooltip()      })      .on('click',function(){lineGroup.toFront(); })      .appendTo(lineGroup);

         }    };    //画折线    line = self.baseDraw('path',{     border      : 1.5,     borderColor : o.color,     isfill      : false,     path        : path    })    .css({zIndex:5})    .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(){lineGroup.toFront(); })    .appendTo(lineGroup);   });   return this;  },  drawArea  : function(){   var self = this,    opts = this.ops,    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.jianju).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个 或者前面的都为bull 修改起点坐标      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.jianju).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.jianju),         L,         x,         y                 ]);       }else{        areaPath.push(x);        areaPath.push(y);       }              //如果是最后一个点       if(n === l - 1){         areaPath.push(x);

            areaPath.push(parseInt(draw.startY-draw.jianju));       }

           //画点       self.baseDraw('circle',{        x : x,             y : y,        r : 4,        fillColor : o.color       })       .attr({data:data[n]})       .on('mouseover',(function(o,x,y){        return function(){         hasSVG          ? (this[0].setAttribute('r','5'),line.attr({'stroke-width':2.5}))          : (this[0].strokeWeight = 3,line[0].strokeWeight = 2.5);                 self.showTooltip(o,x,y,this.attr('data'));        }                          })(o,x,y))       .on('mouseout',function(){        hasSVG         ? (this[0].setAttribute('r','4'),line.attr({'stroke-width':1.5}))         : (this[0].strokeWeight = 1,line[0].strokeWeight = 1.5);        self.hideTooltip()       })       .on('click',function(){areaGroup.toFront(); })        .css({zIndex:10,cursor:'pointer'})       .appendTo(areaGroup);            }    }

        areaPath.push(seal)

        self.baseDraw('path',{     border      : 0,     isfill      : true,     fillColor   : o.color,     opacity     : 0.5,     path        : areaPath    })    .css({zIndex:5})    .appendTo(areaGroup);        line = self.baseDraw('path',{     border      : 2.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.ops,     draw = opts.draw,     chartData     = opts.chartData,    dataLen       = chartData.length,    //多个柱子之间的间距    columnSpace   = 3,    //一个位置中 所有的间隔之和    columnPadding = columnSpace * dataLen + columnSpace,    //每个柱子的宽度    columnSize    = self.ops.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.ops.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).toFixed(0)),       height = Number((data[j] * (draw.yPices / draw.feed)).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];     }else{

           var x     = Number((draw.startX).toFixed(0)),         width = Number((data[j]*((draw.xPices / draw.feed))).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+width/2,y-columnSize];

         }

         self.baseDraw('path',{      border      : 0,      isfill      : true,      fillColor   : o.color,      opacity     : 1,      path        : path     })     .attr({data:data[j]})     .css({zIndex:5,cursor:'pointer'})         .on('mouseover',(function(x,y,d){                    return function(){         

             this.setOpacity(0.85); 

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

         )     .on('mouseout',(function(x,y){      return function(){       this.setOpacity(1);        self.hideTooltip();      }     })(x,y))     .appendTo(colGroup);         }   });   return this;  },  drawPie   : function(){   var self  = this,    opts  = this.ops,    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 ==='object'     ? (data.push((function(o){      var all =0;      for(var i in o)       all+=~~o[i]      return all       })(o.data)))     :data.push(~~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,     pie;    inc = inc + o;   //----------------------生成文字开始----------------------------------------------------------     var 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);

    //-------------------------生成文字结束-------------------------------------------------------    if(hasSVG){     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;     var half_end = half_cumulative * circ; 

         pie = self.baseDraw('pie',{      config  : opts.chartData[i],      s       : start,      e       : end,      r       : radiu,      index   : i     })        }else{     pie=self.baseDraw('pie',{      config  :  opts.chartData[i],      s       :  s,      e       :  e,      r       :  radiu,      index   : i     })             }    pie.css({zIndex:5,cursor:'pointer'})     .attr({move:moveDisplacement})     .on('mouseover',function(){      this.setOpacity(0.85);     })     .on('mouseout',function(){      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',{      x    : x,      y    : y,      fill : '#fff',      'text-anchor':'left'     })     .css({       fontFamily : 'Verdana,Arial,Helvetica,sans-serif',       fontSize   : '12px',       position   : 'absolute',       color      : '#fff',        zIndex     : 10     })     .addText(name)     .appendTo(pieGroup);   });

      },  baseDraw  : function(type,config){   var self = this    arg  = arguments;   return {    rect : function(){     var set    = {};     set.rx     =  set.ry  =  config.arc*30 || 5;     set.width  =  config.width  || 50;     set.height =  config.height || 50;     set.fill   =  config.fill   || '#fff';     set['fill-opacity'] = config.opacity || 0.85;     set['stroke-width'] = config.border  || 2;     set.stroke = config.borderColor  || '#606060';     set.transform = 'translate('+(config.left||0)+','+(config.top||0)+')';        return self.createElement('rect')      .attr(set)          },    text : function(){     return self.createElement('text')      .attr(config)         },    span : function(){     var elem= self.createElement('text')      .attr(config)      .attr({         y : config.y+(arg[2]||15)      })     return elem    },    path : function(){     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 self.createElement('path')      .attr(set);    },    circle : function(){     var set  = {};     set.cx   = config.x;     set.cy   = config.y;     set.r    = config.r;     set.fill = config.fillColor;     return self.createElement('circle')      .attr(set);         },    pie   : function(){     //config,s,e,r,index     var opts     = self.ops,      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,      name     = config.config.name,            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 + 0 * cosEnd,        ry + 0 * sinEnd,       'A', // arcTo       0, // x radius       0, // y radius       0, // slanting       longArc, // long or short arc       0, // clockwise       rx + 0 * cosStart,       ry + 0 * sinStart,       'Z'      ];            return self.baseDraw('path',{      border      : 1,      border      : '#fff',      isfill      : true,      fillColor   : color,      opacity     : 1,      path        : path       })

        }   }[type]();  } }; //---------------------------------------------------------------------------------------------------//如果是vml 修改smipleChart.prototype中的一些方法 !hasSVG   &&extend(smipleChart.prototype,{   baseDraw : function(type,config){        var self   = this,     width  = this.width,     height = this.height,     name   = arguments[2];    return {     rect : function(){         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 self.createElement('roundrect')       .attr(attr)       .css(css)     },     text : function(){      return self.createElement('TextBox')       .attr({inset : "2px,2px,2px,2px" })        },     span : function(){      return self.createElement('span').       css({        position:'absolute',        left : config.x+'px',        top  : config.y+'px'       })     },     path : function(){         var attr = {},       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 = self.createElement()       .attr(attr)       .css(css);      if(config.opacity){       var fill =  self.createElement('fill')        .attr({         type     : 'fill',         color    : config.fillColor||"#C0C0C0",         opacity  : config.opacity        })        .appendTo(elem);       //那这个对象的一个属性引用设置透明的元素 以后会用到       elem.opacity = fill[0];      }            return elem;            },     circle : function(){      var 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 self.createElement()       .attr(attr)       .css(css)      },     pie   : function(){      config,s,e,r,index      var opts  = self.ops,       area  = opts.area,       r     = config.r,       s     = config.s,       e     = config.e,       rx    = area.centerX,       ry    = area.centerY,       sDot  = angle(r,[rx,ry],s,2),       eDot  = angle(r,[rx,ry],e,2),       color = config.config.color,       name  = config.config.name,

           path  = [          'M 0 0 ar',          rx-r,          ry-r,          rx+r,          ry+r,          ~~eDot[0],          ~~eDot[1],          ~~sDot[0],          ~~sDot[1],          'l',          rx,          ry,          'x'       ];      return self.baseDraw('path',{       border      : 1,       border      : '#fff',       isfill      : true,       fillColor   : color,       opacity     : 1,       path        : path           })           }    }[type]();   }  });

    //---------------------------------------------------------------------------------------------------})(document);

     window.onload = function(){ 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',

        data  : [-18,45,-38,29,95,-45,77]    }, {     name: 'frfr',    color: '#AA4643',    data: [-44,12,78,-100,13,4,-56,-34]   }, {    name: 'AAAAA',    color: '#89A54E',

        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 ='区域图标侧标题'     new smipleChart($('area'),config);  config.title.text ='柱状图标'  config.subTitle.text='柱状图标副标题'  config.yUnit.text ='柱状图标侧标题'    config.charts.type ='columns';  config.chartData =[   {

        name  : 'xcv',    color : '#4572A7',

        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  : 'xcv',    color : '#4572A7',

        data  : [433,355,275,null,588,323,576,32,99]    }, {

        name: 'frfr',    color: '#AA4643',    data: [45,666,100,null,677,56,88,633,55,64]    }, {    name: 'AAAAA',    color: '#89A54E',

        data: [55,162,75,null,364,0,637,112,163,615]    }   ]    new smipleChart($('pie'),config);  config.yUnit.lineNum = 2;  config.title.text ='比较小的'  config.subTitle.text='只设置了2条线'  config.yUnit.text ='小测标题' ;    config.charts.type ='line';  config.legend.type='lateral';  new smipleChart($('vv'),config); }</script></body></html>


    最新回复(0)