您的位置:首页 > 其它

VML画柱状图、并图、折线图的封装

2006-06-26 10:49 351 查看
/* 3D统计图绘图类


功能:根据表格数据绘制统计图


作者:LiuZXIT


完成:2003/9/10


备注:在IE6下测试成功


局限性:1.只能针对于单一二维行列式规则TABLE进行绘制


2.TABLE内容必须有左标题和上标题,并且右下部分都必须是数据区


不足:没有支持动态定制数据源,例如用一个XML数据包,有些文字太长会出现显示不好




注意点:


1.htm页面必需包含以下内容


<HTML xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">




<STYLE>





v/:* {

}{behavior:url(#default#VML);}




o/:* {

}{ behavior: url(#default#VML) }




.shape {

}{ behavior: url(#default#VML) }


</STYLE>


2.饼形图和柱状图只能针对一行或一列数据,所以在勾选多行或多列时,只会绘制出勾选的最上面行或最左边列


*/




<script>





function draw3D(arTable,aDiv,asTool,intCol,intRow)

{ //是否画工具栏asTool如不填为N都认为是Y,跳过左边intCol列和表头intRow列省略为1


if(arTable==null || aDiv==null)return;


asTool=(asTool==null?'Y':asTool);


asTool=(asTool.toUpperCase()=='N'?'N':'Y');


intCol=(intCol==null?1:intCol);


intRow=(intRow==null?1:intRow);


intCol=(parseInt(intCol)==NaN?1:parseInt(intCol));


intRow=(parseInt(intRow)==NaN?1:parseInt(intRow));






for(var i=intCol;i<arTable.rows[intRow - 1].cells.length;i++)

{


arTable.rows[intRow - 1].cells[i].innerHTML +='<input type="checkbox" checked name="SelectCol" checked>'


}




for(var i=intRow;i<arTable.rows.length;i++)

{


arTable.rows[i].cells[intCol - 1].innerHTML +='<input type="checkbox" name="SelectRow" checked>'


}






if(asTool=='Y')

{


var strTool='';


strTool += '<span style="font:9pt;"><select id="DrawImg_room" onchange="draw.changeRate(this.value)">';


strTool += '<option value=0.7>0.7';


strTool += '<option value=0.8 selected>0.8<option value=1 >1<option value=2>2<option value=4>4';


strTool += '<option value=6>6<option value=8 >8<option value=10>10</option></select>';


strTool += '<input type="radio" id="DrawImg_type2" name="DrawImg_type" checked><label for="d2">柱状图</label> ';


strTool += '<input type="radio" id="DrawImg_type1" name="DrawImg_type"><label for="d4">饼形图</label> ';


strTool += '<input type="radio" id="DrawImg_type3" name="DrawImg_type"><label for="d3">折线图</label> ';


strTool += '<input type="radio" id="Draw_Compare1" name="Draw_Compare" checked><label for="Draw_Compare1">横比</label> ';


strTool += '<input type="radio" id="Draw_Compare2" name="Draw_Compare"><label for="Draw_Compare2">纵比</label> ';


strTool += '<input type="button" id="Draw_Button" value="画图" onclick="this.DrawImg.draw()"></span>';


aDiv.insertAdjacentHTML("beforeBegin",strTool);


document.all('Draw_Button').DrawImg=this;


}




this.Rate=0.8; //尺寸比例


this.DataSource=new Array(); //数据源


this.DataHead=new Array(); //表头


this.DataKind=new Array(); //种类


this.Color=new Array("#ff0000","#ffA6A6","#ff00ff","#ffaeff","#0000ff","#84aeff","#00ffff","#a6aeff","#00ff00","#b5ffb5","#ffff00","#ffffb5")


this.DrGroup=new Array(); //画了的图的记录集


this.DrawObject=arTable; //放置数据的TABLE


this.DrawDiv=aDiv; //用于画图的DIV,建议用DIV而避免用其他标签


this.IntCol=intCol; //标题列数


this.IntRow=intRow; //标题行数




this.drawPie=DR_drawPie; //画饼型图


this.drawPole=DR_drawPole; //画柱状图


this.drawLine=DR_drawLine; //画折线图


this.changeRate=DR_changeRate; //改变比例尺


this.collectData=DR_collectData; //收集数据


this.draw=DR_draw; //画图




}






function DR_draw()

{


if(DrawImg_type1.checked)this.DrawDiv.innerHTML=draw.drawPie();


if(DrawImg_type2.checked)this.DrawDiv.innerHTML=draw.drawPole();


if(DrawImg_type3.checked)this.DrawDiv.innerHTML=draw.drawLine();


if(document.all('DrawImg_room')!=null)document.all('DrawImg_room').value=1;


}






function DR_collectData()

{


var intRow=this.IntRow,intCol=this.IntCol,tblData=this.DrawObject;


this.DataSource=new Array();


this.DataHead=new Array();


this.DataKind=new Array();




if(Draw_Compare1.checked)

{ //如果是横比




if(intRow > 0)

{




for(var i=intCol;i<tblData.rows[intRow - 1].cells.length;i++)

{


if(tblData.rows[intRow - 1].cells[i].all('SelectCol').checked)this.DataHead[this.DataHead.length++]=tblData.rows[intRow - 1].cells[i].innerText;


}


}




if(intCol > 0)

{




for(var i=intRow;i<tblData.rows.length;i++)

{


if(tblData.rows[i].cells[intCol - 1].all('SelectRow').checked)this.DataKind[this.DataKind.length++]=tblData.rows[i].cells[intCol - 1].innerText;


}


}


var intValue;




for(var i=intRow;i<tblData.rows.length;i++)

{




if(tblData.rows[i].cells[intCol - 1].all('SelectRow').checked)

{


this.DataSource[this.DataSource.length++]=new Array();




for(var j=intCol;j<tblData.rows[i].cells.length;j++)

{




if(tblData.rows[intRow - 1].cells[j].all('SelectCol').checked)

{


this.DataSource[this.DataSource.length - 1].length ++


intValue=parseInt(tblData.rows[i].cells[j].innerText+"");


intValue=(isNaN(intValue)?0:intValue)


this.DataSource[this.DataSource.length - 1][this.DataSource[this.DataSource.length - 1].length - 1]=intValue;


}


}


}


}




}else

{ //否则纵比




if(intRow > 0)

{




for(var i=intCol;i<tblData.rows[intRow - 1].cells.length;i++)

{


if(tblData.rows[intRow - 1].cells[i].all('SelectCol').checked)this.DataKind[this.DataKind.length++]=tblData.rows[intRow - 1].cells[i].innerText;


}


}




if(intCol > 0)

{




for(var i=intRow;i<tblData.rows.length;i++)

{


if(tblData.rows[i].cells[intCol - 1].all('SelectRow').checked)this.DataHead[this.DataHead.length++]=tblData.rows[i].cells[intCol - 1].innerText;


}


}


var intValue;




for(var i=intCol;i<tblData.rows[intCol].cells.length;i++)

{




if(tblData.rows[intRow - 1].cells[i].all('SelectCol').checked)

{


this.DataSource[this.DataSource.length++]=new Array();




for(var j=intRow;j<tblData.rows.length;j++)

{




if(tblData.rows[j].cells[intRow - 1].all('SelectRow').checked)

{


this.DataSource[this.DataSource.length - 1].length ++


intValue=parseInt(tblData.rows[j].cells[i].innerText+"");


intValue=(isNaN(intValue)?0:intValue)


this.DataSource[this.DataSource.length - 1][this.DataSource[this.DataSource.length - 1].length - 1]=intValue;


}


}


}


}


}


}




function DR_drawPie()

{ //arInt:那一组数据


this.collectData();


if(this.DataSource.length<1)return;


var maxScale = 1<<16,intTotal=0


for (var i=0;i<this.DataSource[0].length;i++)intTotal+= parseInt(this.DataSource[0][i]);


this.Rate=1;


var w=1,strObj='DR_Group'




while(w > 0)

{


if(document.all(strObj + w)==null)break;


w++


}


this.DrGroup[this.DrGroup.length++]=(strObj + w);




var str="<v:group id='" +(strObj + w) +"' style='width:500;height:500;position:absolute;' CoordSize='3600,3600'>/n"


//画底下的圆饼


str += "<v:shape style='width:10;height:10;' CoordSize='"+this.Rate+","+this.Rate+"'>/n"


str += "<v:path v='ae 300,200,200,200,3932100,23592960 xe' />/n"


str += "<o:extrusion v:ext='view' on='t' rotationangle='80,-10' backdepth='10' color='#0086c6' />/n"


str += "</v:shape>/n"


//画各部分的饼块


var numStart=0,numScale=0;




for (var i=0;i<this.DataSource[0].length;i++)

{


numScale=(this.DataSource[0][i] / intTotal) * maxScale * 360;


str += "<v:shape style='width:10;height:10;' CoordSize='"+this.Rate+","+this.Rate+"'>/n"


str += "<v:path v='m 300,200 ae 300,200,200,200,"+parseInt(numStart)+","+parseInt(numScale)+" xe' />/n"


str += "<v:fill color='"+this.Color[i * 2 % 12]+"' color2='"+this.Color[(i * 2 % 12) + 1]+"' rotate='t' focus='100%' type='gradient' />/n"


str += "<o:extrusion v:ext='view' on='t' rotationangle='80,-10' backdepth='0' />/n"


str += "</v:shape>/n"


numStart+=numScale


}


//画右边的图例


var intTmp=0




for (var i=0;i<this.DataSource[0].length;i++)

{


str += "<v:rect style='top:"+(i*200)+";left:4500;width:100;height:100;' strokecolor='#0099ff' fillcolor='"+this.Color[(i * 2 % 12)]+"'></v:rect>"


str+="<v:line from='4600,"+(i*200)+"' to='5500,"+(i*200)+"' strokecolor='#ffffff' strokeWeight='2'>"


str += "<v:textbox inset='0pt,0pt,0pt,0pt' style='color:#0099ff;font-size:9pt;'>"+this.DataHead[i]+":"+(i==this.DataSource[0].length - 1?(10000 - intTmp)/100:parseInt(this.DataSource[0][i] / intTotal * 10000) /100)+"%</v:textbox></v:line>"


intTmp += parseInt(this.DataSource[0][i] / intTotal * 10000)


}


str += "</v:group>/n"


return str


}






function DR_drawPole()

{


this.collectData();


if(this.DataSource.length<1)return;


// 数据最大值,数组元素个数 每个柱子的宽度 柱与柱间的间隔


var intMax=0,intTotal=this.DataSource[0].length + 1,intPWidth=parseInt(1800 / intTotal,10),intPad=intPWidth * 2;


intPWidth=(intPWidth>300?300:intPWidth);






for(var i=0;i<this.DataSource[0].length;i++)

{intMax=(intMax < this.DataSource[0][i]?this.DataSource[0][i]:intMax)}


intMax=(parseInt(intMax / Math.pow(10,(intMax+"").length - 1)) + 1) * Math.pow(10,(intMax+"").length - 1)


this.Rate=1;


var w=1,strObj='DR_Group'




while(w > 0)

{


if(document.all(strObj + w)==null)break;


w++


}


this.DrGroup[this.DrGroup.length++]=(strObj + w);




var str="<v:group id='" +(strObj + w) +"' style='width:500;height:500;position:absolute;' CoordSize='3600,3600'>/n"


//画底板


str += "<v:PolyLine Points='400,2400 200,2600 3800,2600 4000,2400' strokecolor='#0099ff'>/n" //底


str += "<v:fill color='#00cfef' angle='45' rotate='t' focus='100%' type='gradient' />/n"


str += "</v:PolyLine>/n"


str += "<v:PolyLine Points='400,2400 200,2600 200,200 400,0 ' strokecolor='#0099ff'>/n" //左


str += "<v:fill color='#00cfef' angle='210' rotate='t' focus='100%' type='gradient' />/n"


str += "</v:PolyLine>/n"


str += "<v:PolyLine Points='400,0 4000,0 4000,2400 400,2400 ' strokecolor='#0099ff'>/n"


str += "<v:fill color='#00cfef' angle='135' rotate='t' focus='100%' type='gradient' />/n" //正


str += "</v:PolyLine>/n"


//画虚线




for(var i=1;i<10;i++)

{


str += "<v:PolyLine filled='false' Points='200,"+(2600 - 240 * i)+" 400,"+(2400 - 240 * i)+" 4000,"+(2400 - 240 * i)+"' strokecolor='#0099ff'>/n"


str += "<v:stroke dashstyle='Dash' />/n"


str += "</v:PolyLine>/n"


}


//画左边的坐标




for(var i=1;i<11;i++)

{


str+="<v:RoundRect style='left:0;top:"+(2600 - 240 * i)+";' strokeColor='transparent'>"


str+="<v:textbox inset='0pt,0pt,0pt,0pt' style='font-size:9pt;color:#0000ff;'>"+(i*(intMax / 10))+"</v:textbox></v:RoundRect>"


}


//画底下的标签




for (var i=0;i<this.DataSource[0].length;i++)

{


str+="<v:RoundRect style='left:"+(400 + parseInt(intPad * (i + 0.5),10) - parseInt((intPWidth / 2)))+";top:2600;' strokeColor='transparent'>"


str+="<v:textbox inset='0pt,0pt,0pt,0pt' style='font-size:9pt;color:#0099ff;'>"+this.DataHead[i]+"</v:textbox></v:RoundRect>"


}




//画柱状图




for(var i=0;i<this.DataSource[0].length;i++)

{


str += "<v:PolyLine Points='"+(400 + parseInt(intPad * (i + 0.5),10))+",2400 "+(400 + parseInt(intPad * (i + 0.5),10))+","+(2400 - parseInt(this.DataSource[0][i]/intMax * 2400,10))+" "+(400 + parseInt(intPad * (i + 0.5),10) + intPWidth)+"," +(2400 - parseInt(this.DataSource[0][i]/intMax * 2400,10))+" "+(400 + parseInt(intPad * (i + 0.5),10) + intPWidth)+",2400 ' strokecolor='#ffffff'>/n"


str += "<v:fill color='"+this.Color[(i % 12)]+"' angle='150' rotate='t' focus='100%' type='gradient' />/n"


str += "<o:extrusion v:ext='view' on='t' backdepth='0' foredepth='"+(parseInt(intPWidth / 10))+"' />/n"


str += "</v:PolyLine>/n"


}


//画每根柱的数据量




for (var i=0;i<this.DataSource[0].length;i++)

{


str+="<v:RoundRect style='left:"+(400 + parseInt(intPad * (i + 0.5),10))+";top:"+(2400 - parseInt(this.DataSource[0][i]/intMax * 2400 + 100))+";' strokeColor='transparent'>"


str+="<v:textbox inset='0pt,0pt,0pt,0pt' style='font-size:9pt;color:#ff00ff;'>"+this.DataSource[0][i]+"</v:textbox></v:RoundRect>"


}


str += "</v:group>"


return str


}




function DR_drawLine()

{ //arInt:那一组数据


this.collectData();


if(this.DataSource.length<1)return;


var intMax=0,intPWidth=parseInt(3600 / (this.DataSource[0].length>1?this.DataSource[0].length - 1:1),10);






for(var i=0;i<this.DataSource.length;i++)

{




for(var j=0;j<this.DataSource[i].length;j++)

{intMax=(intMax < this.DataSource[i][j]?this.DataSource[i][j]:intMax)}


}


intMax=(parseInt(intMax / Math.pow(10,(intMax+"").length - 1)) + 1) * Math.pow(10,(intMax+"").length - 1)


this.Rate=1;


var w=1,strObj='DR_Group'




while(w > 0)

{


if(document.all(strObj + w)==null)break;


w++


}


this.DrGroup[this.DrGroup.length++]=(strObj + w);




var str="<v:group id='" +(strObj + w) +"' style='width:500;height:500;position:absolute;' CoordSize='3600,3600'>/n"


//画底板


str += "<v:PolyLine Points='200,2400 3800,2400 3800,0 200,0 ' strokecolor='#0099ff'>/n"


str += "<v:fill color='#00cfef' angle='135' rotate='t' focus='100%' type='gradient' />/n"


str += "</v:PolyLine>/n"


//画坐标线




for(var i=1;i<10;i++)

{


str += "<v:PolyLine filled='false' Points='200,"+(240 * i)+" 3800,"+(240 * i)+"' strokecolor='#0099ff'/>/n"


}




for(var i=1;i<this.DataSource[0].length;i++)

{


str += "<v:PolyLine filled='false' Points='"+(200 + intPWidth * i)+",0 "+(200 + intPWidth * i)+",2400' strokecolor='#0099ff'>/n"


str += "<v:stroke dashstyle='Dash' />/n"


str += "</v:PolyLine>/n"


}




str += "<v:PolyLine filled='false' Points='200,-100 200,2400 3900,2400' StartArrow='Classic' EndArrow='Classic'>"


str += "<v:stroke StartArrow='Classic' EndArrow='Classic'/>"


str += "</v:PolyLine>"




//画左边的坐标




for(var i=1;i<11;i++)

{


str+="<v:RoundRect style='left:0;top:"+(2400 - 240 * i)+";' strokeColor='transparent'>"


str+="<v:textbox style='font-size:9pt;color:#0099ff;' inset='0pt,0pt,0pt,0pt'>"+(i*(intMax / 10))+"</v:textbox></v:RoundRect>"


}


//画底下的标签




for (var i=0;i<this.DataSource[0].length;i++)

{


str+="<v:line from='"+(200 + intPWidth * i)+",2410' to='"+(450 + intPWidth * i)+",2410' strokecolor='#ffffff'>"


str+="<v:TextBox style='font-size:9pt;color:#0099ff;' inset='0pt,0pt,0pt,0pt'>"+this.DataHead[i]+"</v:TextBox></v:line>"


}


//画折线




for(var j=0;j<this.DataSource.length;j++)

{


var st = "";




for(var i=0;i<this.DataSource[j].length;i++)

{


st +=" " + (200 + intPWidth*i) +","+ (2400 - parseInt(this.DataSource[j][i]/intMax * 2400,10))


}


str += "<v:PolyLine filled='false' Points='"+st+"' strokecolor='"+this.Color[(j % 12)*2]+"'/>/n"


}


//画右边的图例




for (var i=0;i<this.DataKind.length;i++)

{


str+="<v:line from='3850,"+(i*150 + 40)+"' to='3950,"+(i*150 + 40)+"' strokecolor='"+this.Color[(i % 12)*2]+"' strokeWeight='2' />"


str+="<v:line from='3970,"+(i*150)+"' to='4370,"+(i*150)+"' strokecolor='#ffffff' strokeWeight='2'>"


str += "<v:textbox inset='0pt,0pt,0pt,0pt' style='color:#0099ff;font-size:9pt;'>"+this.DataKind[i]+"</v:textbox></v:line>"


}


str += "</v:group>"


return str


}






function DR_changeRate(ai_Rate)

{


if(ai_Rate==this.Rate)return;




for(var i=0;i<this.DrGroup.length;i++)

{




if(document.all(this.DrGroup[i])==null)

{


this.DrGroup=this.DrGroup.slice(0,i).concat(this.DrGroup.slice(i+1))


i--




}else

{document.all(this.DrGroup[i]).coordsize=parseInt(3600 / ai_Rate)+","+parseInt(3600 / ai_Rate);}


}


this.Rate=ai_Rate;


}


</script>


=============JsVML.htm================


<HTML xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">


<HEAD>




<STYLE>





v/:* {

}{behavior:url(#default#VML);}




o/:* {

}{ behavior: url(#default#VML) }




.shape {

}{ behavior: url(#default#VML) }


</STYLE>


<script language="javascript" src="JsVml.js"></script>


</head>


<body>


<table id="tblData" width="60%" border="1" cellpadding="0">


<tr>


<th>年份</th><th>第一2季</th><th>第二4季</th><th>第三季</th><th>第四季</th><th>平均</th>


</tr>


<tr>


<td align="center">1998</td>


<td align="right">2400</td><td align="right">1277</td>


<td align="right">3670</td><td align="right">3176</td>


<td align="right">3176</td>


</tr>


<tr>


<td align="center">1999</td>


<td align="right">2215</td><td align="right">1021</td>


<td align="right">1841</td><td align="right">1952</td>


<td align="right">2215</td>


</tr>


<tr>


<td align="center">2000</td>


<td align="right">1964</td><td align="right">2746</td>


<td align="right">1248</td><td align="right">1878</td>


<td align="right">3670</td>


</tr>


<tr>


<td align="center">2001</td>


<td align="right">2254</td><td align="right">1876</td>


<td align="right">2486</td><td align="right">2000</td>


<td align="right">3670</td>


</tr>


<tr>


<td align="center">2002</td>


<td align="right">2487</td><td align="right">2348</td>


<td align="right">2345</td><td align="right">2456</td>


<td align="right">3670</td>


</tr>


</table>




<div id="tDraw" style="width:600;height:400;overflow:auto;"></div>






<script>





for(var i=1;i<tblData.rows.length;i++)

{


var intQty=0




for(var j=1;j<tblData.rows[i].cells.length - 1;j++)

{


intQty += parseInt(tblData.rows[i].cells[j].innerText,10)


}


tblData.rows[i].cells[j].innerText=parseInt(intQty / (j - 1))


}




var draw=new draw3D(tblData,tDraw);


</script>





转自csdn 效果可以在这看...
http://vbb.iecn.net/showthread.php?threadid=14724
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: