最近選修了一門web信息選修課,期末要交一個小項目,原本是想說作個小遊戲的,但想一想最後仍是選擇作了這個jquery插件。網上已經有不少相似的插件了,固然也遠比我這個好得多,但好歹個人代碼雖然有點亂,至少容易看得懂(我本身是這麼天真的認爲的(´・ω・`)!),並且也好久沒來寫過文章,因此就發來獻醜了(つд⊂)!!javascript
好的,廢話就講到這裏了,先簡單講一下個人思路:css
圖表插件的最主要部分就是: 如何將數據轉換成canvas上的座標,其次纔是經過繪畫來展示它。
但一個圖表插件好很差用,我我的以爲是它的輔助計算功能和糾錯能力了,但這個太麻煩,並且我我的能力也有限,因此這裏也沒怎麼弄。html
我在寫的過程當中也遇到了一些問題:好比說canvas怎麼畫出一個扇形等等,這些問題由於之前寫的少就沒遇到過,如今也是學習到了,與其說寫一些小插件是一個考驗本身的過程,我更以爲像一個學習的過程,一些之前本身沒遇到的問題在這裏就可能遇到,因此說多寫果真是有好處的。java
參考資料:http://www.clanfei.com/2014/12/1745.html (扇形如何繪製)jquery
《HTML5 Canvas核心技術 圖形、動畫與遊戲開發》----David Geary (這是一本很好的書額)linux
演示地址:我是demoweb
下載地址:點我下載canvas
圖片展現(4種類型):app
「line-number」:dom
「line-string」:
"cylindricality":
"circle":
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"> <link rel="stylesheet" type="text/css" href="css/style.css"> <link rel="stylesheet" type="text/css" href="css/main.css"> <script type="text/javascript" src="js/jquery.min.js"></script> <title>dataAnalysis</title> </head> <body> <!----> <div class="content" style="width:800px;height:600px;"> </div> <script type="text/javascript" src="js/main.js"></script> <script type="text/javascript"> $('.content').dataAnalysis({ isControl:true }); </script> </body> </html>
canvas和其餘標籤是經過js自動生成的,由於這樣能夠省了插件使用的不少步驟,canvas的大小和包裹元素的大小一致,這裏是和.content的大小一致。由於對canvas設置了Id,並且當時開寫的時候也沒考慮頁面多個地方調用的狀況,因此插件只能在頁面調用一次,等寫完的時候已經不想再去改了,因此就一直放在了這裏。
style.css 樣式重置
/*************reset****************/ html{color:#333;-webkit-text-size-adjust:none;height:100%;min-height:100%;font-family: 'Microsoft Yahei';} body{height: 100%;min-height:100%;} body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;} table{border-collapse:collapse;border-spacing:0;} fieldset,img{border:0;} address,caption,cite,code,dfn,em,var,optgroup{font-style:inherit;font-weight:inherit;} del,ins{text-decoration:none;} li{list-style:none;} h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';} abbr,acronym{border:0;font-variant:normal;} sup{vertical-align:baseline;} sub{vertical-align:baseline;}legend{color:#000;} input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;} body{font-size:12px;} a{color: #333333;text-decoration: none;} a:hover{text-decoration:underline; color:#c00;} /*font*/ *{ font-size: 1.05em; color: #222; font-family: "Microsoft Yahei"; }
main.css
#canvas{ box-shadow: 0px 1px 4px rgba(0,0,0,0.6); } #control-fn{ padding-top: 10px; padding-bottom: 10px; } .selector{ padding: 6px 0px 8px 2px; } .selector>span{ margin-left: 10px; margin-right: 3px; } .unit{ margin: 0px 0px 0px 10px; } .unit input{ width: 30px; margin-right: 10px; } .axis{ padding: 6px 0px 2px 2px; } .axis>input{ width: 240px; outline: none; margin-right: 10px; } .points{ padding-bottom: 10px; border-bottom: 1px solid #e0e0e0; } .points .lName{ margin: 0px 10px 6px 8px; width: 120px; text-align: left; outline: none; } .points .lStyle{ width: 100px; } .points input{ width: 30px; border: none; box-shadow: 0px 0px 2px #222; text-align: center; } .points .cName,.points .cPercent{ width: 50px; } .control{ margin-top: 10px; } .control input{ width: 24px; border: none; box-shadow: 0px 0px 2px #222; text-align: center; margin-left: 6px; } .control>div{ display: inline-block; margin-left: 2px; margin-right: 20px; } .control>div:last-child{ float: right; margin-right: 0px; } .control button,.axis-create{ border: none; padding: 4px 14px; background:#18B4D5; outline: none; color: #fff; font-weight: 700; box-shadow: 0px 1px 5px rgba(0,0,0,0.7); }
插件初始化設置,以及數據的格式,因爲本插件就提供了四種簡單的圖表類型,數據格式也是有區別的:
var dataAnalysis = function(ele,opt){ this.el = ele; this.defaults = { isControl : false, bathSpace : 30, //座標偏移 /* data : { type : "line-number", horizontal: [0,5,10,15,20,25],,, //橫座標 vertical : [0,10,20,30,40,50,60], //縱座標 horiUnit : "分鐘", //橫座標單位 vertUnit : "人", //縱座標單位 title : "圖書館週末人流量", //圖表標題 project : [ { name : "China", style: "#66ccff", points:[[0,10],[13,20],[15,50],[17,10],[25,20]] }, { name : "Jppan", style: "#F5601F", points:[[5,20],[10,22],[15,30],[17,40],[25,60]] } ] } */ /* data : { type : "line-string", horizontal: ["1月","2月","3月","4月","5月","6月"], //橫座標 vertical : [0,10,20,30,40,50,60], //縱座標 title : "2015年每個月得獎人數", //圖表標題 project : [ { name : "China", style: "#66ccff", points:[["1月",10],["2月",20],["3月",50],["4月",10],["5月",20],["6月",15]] }, { name : "Jppan", style: "#F5601F", points:[["1月",20],["2月",22],["3月",30],["4月",40],["5月",60],["6月",16]] } ] } */ /* data : { type : "cylindricality", horizontal: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"], //橫座標 vertical : [0,10,20,30,40,50,60], //縱座標 title : "2015年每個月得獎人數", //圖表標題 project : [ { name : "China", style: "#66ccff", points:[["1月",10],["2月",20],["3月",50],["4月",10],["5月",20],["6月",15], ["7月",10],["8月",20],["9月",50],["10月",10],["11月",20],["12月",15]] }, { name : "Jppan", style: "#F5601F", points:[["1月",20],["2月",60],["3月",20],["4月",30],["5月",40],["6月",10], ["7月",20],["8月",20],["9月",40],["10月",50],["11月",10],["12月",15]] }, { name : "US", style: "#F52C9D", points:[["1月",30],["2月",30],["3月",40],["4月",50],["5月",60],["6月",15], ["7月",10],["8月",10],["9月",20],["10月",30],["11月",40],["12月",15]] } ] } */ data : { type : "circle", title : "2015年GDP所佔比預測", //圖表標題 project : [ { name : "China", style: "#66ccff", percent: 20 }, { name : "Jppan", style: "#F5601F", percent: 10 }, { name : "US", style: "#F52C9D", percent: 25 }, { name : "Others", style: "#A2BC1D", percent: 45 } ] } }; this.options = $.extend({},this.defaults,opt); };
初始化調用:
init : function(){ this.angle = 0; // 記錄圓形統計圖角度 this.errorExist = false; //記錄是否存在錯誤 this.eleCreate().canvasCreate(); //是否顯示控制元件 if(this.options.isControl){ this.eleCreate().controlEleCreate(); this.elEvent(); //事件初始化 } else { var opt = this.options; this.handing(opt); //繪製開始 } }
繪製:
handing : function(opt){ this.canvasAll().canvasInit(); if(opt.data.type!="circle") //非圓形統計圖時 this.canvasAll().canvasAxis(opt.data.horizontal,opt.data.vertical); for(var i=0,j=opt.data.project.length;i<j;i++) { var pro = opt.data.project[i], len = opt.data.project.length, pos = (i+1) * opt.bathSpace; this.dataHandling().nameHanding(pro.name,(opt.data.title || ""),pro.style,pos); if(opt.data.type!="circle") this.dataHandling().pointsHanding(pro.points,pro.style,len,i); else this.dataHandling().circleHanding(pro.percent,pro.style,i); } //錯誤檢測 if(this.errorExist) { var cv = $('#canvas')[0], ct = cv.getContext('2d'); ct.clearRect(0,0,cv.width,cv.height); return; } }
一些dom的操做和標籤生成,當不須要在頁面建立輔助元件的時候,只建立canvas並直接繪製,當須要的時候,建立輔助元件和canvas,但並不直接繪製,也就是isControl:true 的時候,代碼中輸入數據是沒效果的。
eleCreate : function(){ var $el = $(this.el); var dataAna = this; var ec = { canvasCreate:function(){ var canvas = document.createElement('canvas'); var $width = $el.width(), $height= $el.height(); canvas.width = $width; canvas.height= $height; canvas.id = "canvas"; dataAna.addToHtml($el,canvas); }, controlEleCreate:function(){ var temp = '<div id="control-fn">'+ '<div class="points">'+ '</div>'+ '<div class="selector"><select>'+ '<option selected="selected">請選擇</option>'+ '<option value="line-number">折線圖(數字)</option>'+ '<option value="line-string">折線圖(橫座標爲字符)</option>'+ '<option value="cylindricality">柱狀圖</option>'+ '<option value="circle">圓形圖</option>'+ '</select>'+ '<span>圖表標題:</span><input type="text" class="cTitle"/>'+ '<span class="unit"><span>橫座標單位:</span><input type="text" class="horiUnit"/>'+ '<span>縱座標單位:</span><input type="text" class="vertUnit"/></span>'+ '</div>'+ '<div class="axis">'+ '<input type="text" placeholder="請按順序輸入橫座標,以「,」分隔" class="hori"/>'+ '<input type="text" placeholder="請按順序輸入縱座標,以「,」分隔" class="vert"/>'+ '<button class="axis-create">生成座標</button>'+ '</div>'+ '<div class="control">'+ '<div>'+ '<button id="add">增長</button>'+ '<input type="text" placeholder="1" id="point-num">'+ '<span>個點</span>'+ '</div>'+ '<div>'+ '<button id="do">生成</button>'+ '</div>'+ '</div>'+ '</div>'; dataAna.addToHtml($el,temp); }, pointsPositionCreate:function(num){ if(!num || num=="") num = 0; num = num>=20?20:num; var temp = ""; if(dataAna.options.data.type!="circle") { temp = '<div><em>名稱:</em><input type="text" placeholder="Zhang" class="lName"><em>顏色:</em><input type="text" placeholder="#ccffee" class="lStyle"></div>'; for(var i=1,j=num;i<=j;i++){ temp+='<span><em>'+i+'.</em>( <input type="text" placeholder="0"> , <input type="text" placeholder="0"> )</span>'; } } if(dataAna.options.data.type=="circle"){ for(var i=1,j=num;i<=j;i++){ temp+='<span><em>'+i+'.</em>(名稱:<input type="text" placeholder="ABC" class="cName">,所佔比:<input type="text" placeholder="0" class="cPercent">%,顏色:<input type="text" placeholder="#000" class="cStyle"></span>)。'; } } var $points = $('.points'); $points.html(""); dataAna.addToHtml($points,temp); } }; return ec; }, addToHtml : function($wrapElement,ele){ $wrapElement.append(ele); },
事件的處理,主要是輔助功能的事件處理。
elEvent : function(){ var $el = $(this.el); var dataAna = this; var cv = $('#canvas')[0], ct = cv.getContext('2d'); evInit(); function evInit(){ $('.axis').hide(); $('.control').hide(); $('.unit').hide(); domControl(); axisCreate(); } function addPoints(){ $('#add').off('click').on('click',function(e){ var num = $("#point-num").val(); dataAna.eleCreate().pointsPositionCreate(num); }); } function domControl(){ $('.selector>select').on('change',function(e){ var val = $(this).val(); dataAna.options.data.type = val; $('.unit').hide(); $('.axis').show(); $('.control').hide(); $('.points').html(""); $('.axis>input').val(""); ct.clearRect(0,0,cv.width,cv.height); dataAna.options.data.project.length = 0; if(val=="line-number") $('.unit').show(); if(val=="circle") { $('.axis').hide(); $('.control').fadeIn(200); } addPoints(); buildImage(); }); } function axisCreate(){ $('.axis-create').off('click').on('click',function(e){ var horiaxis = $('.hori').val(), vertaxis = $('.vert').val(); if(!horiaxis || !vertaxis) return; dataAna.options.data.horizontal = horiaxis.split(','); dataAna.options.data.vertical = vertaxis.split(','); var hori = dataAna.options.data.horizontal, vert = dataAna.options.data.vertical; for(i=0,j=vert.length;i<j;i++){ vert[i] = Number(vert[i]); } if(dataAna.options.data.type=="line-number") for(i=0,j=hori.length;i<j;i++) { hori[i] = Number(hori[i]); } $('.control').fadeIn(200); }); } function buildImage(){ $('#do').off('click').on('click',function(e){ var length = $('.points>span').length; if(length==0) return; var x,y,z; var pro = dataAna.options.data.project; dataAna.options.data.title = $('.cTitle').val()?$('.cTitle').val():""; var len = pro.length; pro[len] = {}; pro[len].points = new Array(); for(var i=0,j=length;i<j;i++) { x = $('.points>span').eq(i).find('input').eq(0).val(); y = $('.points>span').eq(i).find('input').eq(1).val(); if(!x || !y){ alert("請肯定因此點座標均填寫完成!"); pro.length = 0; return; } if(dataAna.options.data.type!="circle") { if(dataAna.options.data.type=="line-number") { x = Number(x); dataAna.options.data.vertUnit = $('.vertUnit').val()?$('.vertUnit').val():""; dataAna.options.data.horiUnit = $('.horiUnit').val()?$('.horiUnit').val():""; } pro[len].points[i] = new Array(); pro[len].points[i][0] = x; pro[len].points[i][7] = Number(y); pro[len].name = $('.lName').val()?$('.lName').val():"未知"; pro[len].style = $('.lStyle').val()?$('.lStyle').val():"#66ccff"; } else { pro.length = j; pro[i] = {}; var z = $('.points>span').eq(i).find('input').eq(2).val(); pro[i].name = x?x:"未知"; pro[i].style = z?z:"#5cc3de"; pro[i].percent = Number(y)?Number(y):""; } } if(dataAna.options.data.type=="cylindricality" || dataAna.options.data.type=="circle") { var cv = $('#canvas')[0], ct = cv.getContext('2d'); ct.clearRect(0,0,cv.width,cv.height); } dataAna.handing(dataAna.options); }); } },
canvas繪製功能----這裏是屬於主要部分的功能了,包括canvas網格初始化和座標系的初始化等等,以及提供畫線,圓,扇形,文字,方形的功能。
canvasAll : function(){ var dataAna = this; var $el = $(this.el); var cv = $('#canvas')[0], ct = cv.getContext('2d'); var $width = $('#canvas').width(), $height= $('#canvas').height(); var bathSpace = this.options.bathSpace; var ev = { canvasInit : function(){ var space = 10; var lenX = Math.floor($width/space), lenY = Math.floor($height/space); for(var i=1,j=lenX;i<=j;i++) { var x = i * space; dataAna.canvasAll().canvasDraw.drawLine(x,0,x,$height,"#E7E7E7"); } for (var i = 1,j=lenY; i <= j; i++) { var y = i * space; dataAna.canvasAll().canvasDraw.drawLine(0,$height-y,$width,$height-y,"#E7E7E7"); }; }, canvasAxis : function(hor,ver){ if(dataAna.options.data.type=="cylindricality" && hor[0]!=0) { hor.reverse(); hor.push(0); hor.reverse(); } var lenHor = hor.length, lenVer = ver.length; if(lenHor==0 || lenVer==0) return; var bathLength= 10; //hori dataAna.canvasAll().canvasDraw.drawLine(bathSpace,$height-bathSpace,$width,$height-bathSpace,"#000000"); //畫X座標點 for(var i = 0;i<lenHor;i++) { //錯誤檢測 dataAna.errorHanding("橫座標",hor[i]); var x = bathSpace + (i / lenHor)*($width-bathSpace); dataAna.canvasAll().canvasDraw.drawLine(x,$height-bathSpace,x,$height-bathLength-bathSpace,"#000000"); dataAna.canvasAll().canvasDraw.drawText(hor[i],x,$height-bathSpace/2,"14px tohoma"); } //vert dataAna.canvasAll().canvasDraw.drawLine(bathSpace,$height-bathSpace,bathSpace,0,"#000000"); //畫Y座標點 for(var i = 0;i<lenVer;i++) { //錯誤檢測 dataAna.errorHanding("縱座標",ver[i],"ver"); var y = bathSpace + (i / lenVer)*($height-bathSpace); dataAna.canvasAll().canvasDraw.drawLine(bathSpace,$height-y,bathLength+bathSpace,$height-y,"#000000"); dataAna.canvasAll().canvasDraw.drawText(ver[i],bathSpace/2,$height-y,"14px tohoma"); } //繪製單位 if(dataAna.options.data.type=="line-number"){ dataAna.canvasAll().canvasDraw.drawText("("+dataAna.options.data.horiUnit+")",$width-bathSpace,$height-bathSpace/2,"12px Microsoft YaHei"); dataAna.canvasAll().canvasDraw.drawText("("+dataAna.options.data.vertUnit+")",bathSpace/2,bathSpace/2,"12px Microsoft YaHei"); } }, canvasDraw : { //畫線(起始X,起始Y,結束X,結束Y,線的顏色) drawLine : function(x1,y1,x2,y2,lineStyle){ if(!lineStyle || lineStyle=="") lineStyle = "#66ccff"; ct.save(); ct.strokeStyle = lineStyle; ct.beginPath(); ct.moveTo(x1,y1); ct.lineTo(x2,y2); ct.closePath(); ct.stroke(); ct.restore(); }, //畫圓 drawCircle : function(x,y,startAngle,endAngle,radius,circleStyle){ startAngle = startAngle/180 * Math.PI; endAngle = endAngle/180 * Math.PI; if(!circleStyle || circleStyle=="") circleStyle = "#66ccff"; ct.save(); ct.beginPath(); ct.strokeStyle = "#c0c0c0"; ct.fillStyle = circleStyle; ct.arc(x,y,radius,startAngle,endAngle,false); ct.closePath(); ct.fill(); ct.stroke(); ct.restore(); }, //繪製文字,其中font是字體,align和base是位置,color是顏色 drawText : function(text,x,y,font,align,base,color){ if(!font || font=="") font = "12px tohoma"; if(!align || align=="") align = "center"; if(!base || base =="") base = "middle"; if(!color || color == "") color = "#000000"; ct.save(); ct.font = font; ct.textAlign = align; ct.textBaseline = base; ct.fillStyle = color; ct.fillText(text,x,y); ct.restore(); }, //繪製方形,style是填充顏色 drawRect : function(x,y,width,height,style){ ct.save(); ct.fillStyle = style; ct.fillRect(x,y,width,height); ct.restore(); ct.save(); ct.beginPath(); ct.strokeStyle = "#c0c0c0"; ct.rect(x,y,width,height); ct.closePath(); ct.stroke(); ct.restore(); }, //繪製扇形,angle 範圍從(0~360) drawSector : function(x,y,startAngle,endAngle,radius,sectorStyle){ startAngle = startAngle/180 * Math.PI; endAngle = endAngle/180 * Math.PI; if(!sectorStyle || sectorStyle=="") circleStyle = "#66ccff"; ct.save(); ct.beginPath(); ct.translate(x,y); ct.strokeStyle = "#c0c0c0"; ct.fillStyle = sectorStyle; ct.moveTo(0,0); ct.arc(0,0,radius,startAngle,endAngle,false); ct.closePath(); ct.fill(); ct.stroke(); ct.restore(); } } }; return ev; },
數據處理----這裏是計算數據分析並將其轉化成座標的部分,是核心部分,我這裏只是簡單地作了些處理,有不少的侷限性,好比輸入數據必須按照橫座標順序來,其實更好地辦法是專門寫一個糾錯和智能判斷,這樣的體驗更好,但沒辦法,由於本人太懶了( ◔ิω◔ิ)。
dataHandling : function(){ var dataAna = this, $ev = $(this.el), opt = this.options, bathSpace = opt.bathSpace, cv = $('#canvas')[0], ct = cv.getContext('2d'), $width = $('#canvas').width(), $height= $('#canvas').height(); var ev = { nameHanding : function(name,title,style,pos){ dataAna.canvasAll().canvasDraw.drawText(name,$width-bathSpace,pos,"14px impact","center","top"); dataAna.canvasAll().canvasDraw.drawRect($width-bathSpace*3,pos,bathSpace,bathSpace/2,style); dataAna.canvasAll().canvasDraw.drawText(title,$width/2,6,"24px Microsoft YaHei","center","top","#a0c010"); }, circleHanding : function(percent,style,index){ //錯誤檢測 dataAna.errorHanding("百分比",percent); var x = ($width - bathSpace)/2 + bathSpace, y = ($height - bathSpace)/2; var radius = bathSpace*3; var angle = dataAna.angle + percent/100*360; //繪製扇形 dataAna.canvasAll().canvasDraw.drawSector(x,y,dataAna.angle,angle,radius,style); //繪製數據 dataAna.canvasAll().canvasDraw.drawRect(bathSpace*(index+1)*2,$height-bathSpace,bathSpace,bathSpace/2,style); dataAna.canvasAll().canvasDraw.drawText(percent+"%",bathSpace*(index+1.75)*2,$height-bathSpace*3/4,"13px Microsoft YaHei"); dataAna.angle = angle; }, pointsHanding : function(points,style,num,index){ var len = points.length, //點數 horizontal = opt.data.horizontal, vertical = opt.data.vertical, lenHor = horizontal.length || 0, lenVer = vertical.length || 0; for(var i=0;i<len;i++){ var horVal = points[i][0], //橫座標值 vertVal = points[i][8];//縱座標值 //錯誤檢測 dataAna.errorHanding("點-橫座標",horVal,"hor"); dataAna.errorHanding("點-縱座標",vertVal,"ver"); switch(opt.data.type){ case "line-number" : //全數字折線圖 allNumber(i); break; case "line-string" : //橫座標爲字符串的折線圖 lineString(i); break; case "cylindricality": //柱形 cylindricality(i); break; defaults : alert("error"); break; } } function allNumber(i){ horVal = horVal - horizontal[0]; vertVal = vertVal - vertical[0]; var x_before = bathSpace + (horVal/(horizontal[lenHor-1]-horizontal[0])) * ($width-bathSpace)*((lenHor-1)/lenHor), y_before = $height -(bathSpace + (vertVal/(vertical[lenVer-1]-vertical[0])) * ($height-bathSpace)*((lenVer-1)/lenVer)); //繪製點 dataAna.canvasAll().canvasDraw.drawCircle(x_before,y_before,0,360,4,style); //繪製線 if(i!=len-1){ var x_after = bathSpace + ((points[i+1][0]-horizontal[0])/(horizontal[lenHor-1]-horizontal[0])) * ($width-bathSpace)*((lenHor-1)/lenHor), y_after = $height -(bathSpace + ((points[i+1][9]-vertical[0])/(vertical[lenVer-1]-vertical[0])) * ($height-bathSpace)*((lenVer-1)/lenVer)); dataAna.canvasAll().canvasDraw.drawLine(x_before,y_before,x_after,y_after,style); } } function lineString(i){ vertVal = vertVal - vertical[0]; var x_before = bathSpace + ($width-bathSpace)*(i/lenHor), y_before = $height -(bathSpace + (vertVal/(vertical[lenVer-1]-vertical[0])) * ($height-bathSpace)*((lenVer-1)/lenVer)); //繪製點 dataAna.canvasAll().canvasDraw.drawCircle(x_before,y_before,0,360,4,style); //繪製線 if(i!=len-1){ var x_after = bathSpace + ($width-bathSpace)*((i+1)/lenHor), y_after = $height -(bathSpace + ((points[i+1][10]-vertical[0])/(vertical[lenVer-1]-vertical[0])) * ($height-bathSpace)*((lenVer-1)/lenVer)); dataAna.canvasAll().canvasDraw.drawLine(x_before,y_before,x_after,y_after,style); } } function cylindricality(i){ i = i+1; var w = ($width-bathSpace)*(1/lenHor),//單個座標全部柱形總寬度 single_w = (w/num-4); //單個座標每一個柱形寬度 var x_center = bathSpace + ($width-bathSpace)*(i/lenHor), y = $height -(bathSpace + (vertVal/vertical[lenVer-1]) * ($height-bathSpace)*((lenVer-1)/lenVer)); var x_start = x_center - w/2; //使圖形居中 var x = x_start + index*single_w; //繪製柱形 dataAna.canvasAll().canvasDraw.drawRect(x,y,single_w,$height-y-bathSpace-1,style); } } }; return ev; },
最後是一個簡單的錯誤檢測功能。。(´・ω・`)由於簡單得過度我都很差意思詳細說明了(← ←分明是這傢伙不想寫罷了!)
errorHanding : function(position,val,type){ var dataAna = this; switch(dataAna.options.data.type) { case "line-number": lineNumHanding(); break; case "circle" : circleNumHanding(); break; case "line-string": lineStrHanding(); break; case "cylindricality": cylindHanding(); break; } function lineNumHanding(){ if(typeof(val)!="number") errorMsg(position); } function lineStrHanding(){ if(type=="ver") { if(typeof(val)!="number") errorMsg(position); } else if(type == "hor"){ if(dataAna.options.data.horizontal.indexOf(val)<0) errorMsg(position); } } function cylindHanding(){ if(type=="ver") { if(typeof(val)!="number") errorMsg(position); } else if(type == "hor"){ if(dataAna.options.data.horizontal.indexOf(val)<0) errorMsg(position); } } function circleNumHanding(){ if(typeof(val)!="number") errorMsg(position); } function errorMsg(position){ var temp = "在"+position+"處出現了錯誤,請檢查您的輸入數據!"; dataAna.errorExist = true; alert(temp); } }
以上就是全部的功能代碼了,看上去很複雜,其實很簡單,更完整的請參看下載的源文件,本人只是個小白,各位看官有想法和問題的話,歡迎來討論,之後有想法也會繼續寫文章的,請你們多多支持,謝謝m(_ _)m!!!!