利用Javascript 结合 VML 生成三维报表(饼图)[原创]
前几天看了Jmtek 的 http://www.cnblogs.com/jmtek/archive/2006/02/23/336073.html 这篇文章,写得的确不错,控件也非常好。只是只能供我们使用 DotNet 的朋友们使用。最近在网上比较流行 AJAX 技术,于是萌生了在 AJAX 下实现这种效果的想法。最终决定采用一个文本文件作为数据源,Javascript 动态生成 VML 代码。实现后的效果还比较可以,生成的图表效果和 Jmtek 的控件效果差不多,并且能够在文本数据内容发生改变时无刷新的更新图表,更新数据也非常方便。
这段代码的最大特点是:移植性非常好,只需将两个文件放在任意一个目录下即可运行,这样爱好 JAVA 的朋友也可实现这种效果了。
使用说明:将代码分别保存为相应的文件,放在同一个目录下,浏览网页即可看到生成的三维图表。
欢迎大家与我交流,我的QQ号是:512754784
代码文件下载:/Files/Infinity/成绩三维报表.rar
示例图片如下:
------------------------------------------------------------------------------------------------------------
成绩三维报表.htm
------------------------------------------------------------------------------------------------------------
<!--
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ┃
┃ 摘 要: 统计图--饼图 ┃
┃ 作 者: 无涯 ┃
┃ 创建日期:2006年02月28日 ┃
┃ 完成日期:2006年02月28日 ┃
┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
-->
<HTML xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<HEAD>
<title></title>
<Meta http-equiv="Refresh" Content="3">
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
<STYLE> v\:* { Behavior: url(#default#VML) }
o\:* { behavior: url(#default#VML) }
</STYLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
var onit=true;
var num=0;
var stat_array = new Array();
function moveup(iteam,top,txt,rec)
{
temp = eval(iteam);
tempat = eval(top);
temptxt = eval(txt);
temprec = eval(rec);
at = parseInt(temp.style.top);
temprec.style.display = "";
if (num > 27)
{
temptxt.style.display = "";
}
if(at>(tempat-28) && onit)
{
num++;
temp.style.top = at-1;
Stop=setTimeout("moveup(temp,tempat,temptxt,temprec)",10);
}
else
{
return;
}
}
function movedown(iteam,top,txt,rec)
{
temp = eval(iteam);
temptxt = eval(txt);
temprec = eval(rec);
clearTimeout(Stop);
temp.style.top = top;
num = 0;
temptxt.style.display = "none";
temprec.style.display = "none";
}
function ontxt(iteam,top,txt,rec)
{
temp = eval(iteam);
temptxt = eval(txt);
temprec = eval(rec);
if (onit)
{
temp.style.top = top-28;
temptxt.style.display = "";
temprec.style.display = "";
}
}
function movereset(over)
{
if (over==1)
{
onit=false;
}
else
{
onit=true;
}
}
function createXMLHttp()
{
var xmlObj;
if(window.XMLHttpRequest)
{
xmlObj = new XMLHttpRequest();
if(xmlObj.overrideMimeType)
xmlObj.overrideMimeType('text/xml');
}
else if(window.ActiveXObject)
{
try
{
xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
return xmlObj;
}
catch(e)
{
try
{
xmlObj = new ActiveXObject("Msxml2.XMLHTTP");
return xmlObj;
}
catch(e)
{
try
{
xmlObj=new ActiveXObject("MSXML2.ServerXMLHTTP");
return xmlObj;
}
catch (e)
{
return false;
}
}
}
}
else
{
return false;
}
}
function readFile(url)
{
if (createXMLHttp())
{
xmlUrl = createXMLHttp();
}
xmlUrl.Open("GET",url);
xmlUrl.Send();
while (xmlUrl.readyState == 4)
{
return bytes2BSTR(xmlUrl.ResponseBody);
}
}
function table(num,table_left,table_top,all_width,all_height,table_title,unit)
{
var allvalues=0;
var color = new Array();
var bg_color = new Array(num);
var pie = new Array(num);
color[0]="#ff8c19";
color[1]="#ff1919";
color[2]="#ffff19";
color[3]="#1919ff";
color[4]="#19ff19";
color[5]="#fc0000";
color[6]="#3cc000";
color[7]="#ff19ff";
color[8]="#993300";
color[9]="#f60000";
for (i=0,j=0; i<num; i++,j++)
{
bg_color[i] = color[j];
if (j == color.length)
{
j = -1;
}
}
for (i=0; i<num; i++)
{
allvalues += stat_array[0][i];
}
var k = 0;
for (i=0; i<num-1; i++)
{
pie[i] = parseInt((stat_array[0][i])/allvalues*10000)/10000;
k += pie[i];
}
pie[num-1] = 1-k;
document.writeln("<v:shapetype id='Cake_3D' coordsize='21600,21600' o:spt='95' adj='11796480,5400' path='al10800,10800@0@0@2@14,10800,10800,10800,10800@3@15xe'></v:shapetype>");
document.writeln("<v:shapetype id='3dtxt' coordsize='21600,21600' o:spt='136' adj='10800' path='m@7,l@8,m@5,21600l@6,21600e'>");
document.writeln("<v:path textpathok='t' o:connecttype='custom' o:connectlocs='@9,0;@10,10800;@11,21600;@12,10800' o:connectangles='270,180,90,0'/>");
document.writeln("<v:textpath on='t' fitshape='t'/>");
document.writeln("<o:lock v:ext='edit' text='t' shapetype='t'/>");
document.writeln("</v:shapetype>");
document.writeln("<v:rect id='background' style='position:absolute;left:" + table_left + "px;top:" + table_top + "px;WIDTH:" + all_width + "px;HEIGHT:" + all_height + "px;' fillcolor='#EFEFEF' strokecolor='gray'>");
document.writeln("<v:shadow on='t' type='single' color='silver' offset='4pt,4pt'/>");
document.writeln("</v:rect>");
document.writeln("<v:group ID='table' style='position:absolute;left:" + table_left + "px;top:" + table_top + "px;WIDTH:" + all_width + "px;HEIGHT:" + all_height + "px;' coordsize = '21000,11500'>");
document.writeln("<v:Rect style='position:relative;left:500;top:200;width:20000;height:800'filled='false' stroked='false'>");
document.writeln("<v:TextBox inset='0pt,0pt,0pt,0pt'>");
document.writeln("<table width='100%' border='0' align='center' cellspacing='0'>");
document.writeln("<tr>");
document.writeln("<td align='center' valign='middle'><div style='font-size:15pt; font-family:黑体;'><B>" + table_title + "</B></div></td>");
document.writeln("</tr>");
document.writeln("</table>");
document.writeln("</v:TextBox>");
document.writeln("</v:Rect> ");
document.writeln("<v:rect id='back' style='position:relative;left:500;top:1000;width:20000; height:10000;' onmouseover='movereset(1)' onmouseout='movereset(0)' fillcolor='#9cf' strokecolor='#888888'>");
document.writeln("<v:fill rotate='t' angle='-45' focus='100%' type='gradient'/>");
document.writeln("</v:rect>");
document.writeln("<v:rect id='back' style='position:relative;left:15000;top:1400;width:5000; height:" + ((num+1)*9000/11+200) + ";' fillcolor='#9cf' stroked='t' strokecolor='#0099ff'>");
document.writeln("<v:fill rotate='t' angle='-175' focus='100%' type='gradient'/>");
document.writeln("<v:shadow on='t' type='single' color='silver' offset='3pt,3pt'/>");
document.writeln("</v:rect>");
document.writeln("<v:Rect style='position:relative;left:15500;top:1500;width:4000;height:700' fillcolor='#000000' stroked='f' strokecolor='#000000'>");
document.writeln("<v:TextBox inset='8pt,4pt,3pt,3pt' style='font-size:11pt;'><div align='left'><font color='#ffffff'><B>总数:" + allvalues + unit + "</B></font></div></v:TextBox>");
document.writeln("</v:Rect> ");
for (i=0; i<num; i++)
{
document.writeln("<v:Rect id='rec" + i + "' style='position:relative;left:15400;top:" + Math.round((i+1)*9000/11+1450) + ";width:4300;height:800;display:none' fillcolor='#efefef' strokecolor='" + bg_color[i] + "'>");
document.writeln("<v:fill opacity='.6' color2='fill darken(118)' o:opacity2='.6' rotate='t' method='linear sigma' focus='100%' type='gradient'/>");
document.writeln("</v:Rect>");
document.writeln("<v:Rect style='position:relative;left:15500;top:" + Math.round((i+1)*9000/11+1500) + ";width:600;height:700' fillcolor='" + bg_color[i] + "' stroked='f'/>");
document.writeln("<v:Rect style='position:relative;left:16300;top:" + Math.round((i+1)*9000/11+1500) + ";width:3400;height:700' filled='f' stroked='f'>");
document.writeln("<v:TextBox inset='0pt,5pt,0pt,0pt' style='font-size:9pt;'><div align='left'>" + stat_array[1][i] + ":" + stat_array[0][i] + unit + "</div></v:TextBox>");
document.writeln("</v:Rect> " );
}
document.writeln("</v:group>");
var k1 = 180;
var k4 = 10;
for (i=0; i<num; i++)
{
k2 = 360 * pie[i]/2;
k3 = k1 + k2;
if (k3 >= 360)
{
k3 = k3 - 360;
}
kkk = (-11796480 * pie[i] + 5898240);
k5 = 3.1414926 * 2 * (180-(k3-180))/360;
R = all_height/2;
txt_x = table_left + all_height/8-30 + R + R * Math.sin(k5) * 0.7;
txt_y = table_top + all_height/14-39 + R + R * Math.cos(k5) * 0.7 * 0.5;
titlestr = " 名 称:" + stat_array[1][i] + " 数 值:" + stat_array[0][i] + unit + " 所占比例:" + pie[i]*100 + "% "
document.writeln("<div style='cursor:hand;'>");
document.writeln("<v:shape id='cake" + i + "' type='#Cake_3D' title='" + titlestr + "'");
document.writeln("style='position:absolute;left:" + table_left+all_height/8 + "px;top:" + table_top+all_height/14 + "px;WIDTH:" + all_height + "px;HEIGHT:" + all_height + "px;rotation:" + k3 + ";z-index:" + k4 + "'");
document.writeln("adj='" + kkk + ",0' fillcolor='" + bg_color[i] + "' onmouseover='moveup(cake" + i + "," + (table_top+all_height/14) + ",txt" + i + ",rec" + i + ")'; onmouseout='movedown(cake" + i + "," + (table_top+all_height/14) + ",txt" + i + ",rec" + i + ");'>");
document.writeln("<v:fill opacity='60293f' color2='fill lighten(120)' o:opacity2='60293f' rotate='t' angle='-135' method='linear sigma' focus='100%' type='gradient'/>");
document.writeln("<o:extrusion v:ext='view' on='t'backdepth='25' rotationangle='60' viewpoint='0,0'viewpointorigin='0,0' skewamt='0' lightposition='-50000,-50000' lightposition2='50000'/>");
document.writeln("</v:shape>");
document.writeln("<v:shape id='txt" + i + "' type='#3dtxt' style='position:absolute;left:" + txt_x + "px;top:" + txt_y + "px;z-index:20;display:none;width:50; height:18;' fillcolor='#ffffff'");
document.writeln("onmouseover='ontxt(cake" + i + "," + (table_top+all_height/14) + ",txt" + i + ",rec" + i + ")'>");
document.writeln("<v:fill opacity='60293f' color2='fill lighten(120)' o:opacity2='60293f' rotate='t' angle='-135' method='linear sigma' focus='100%' type='gradient'/>");
document.writeln("<v:textpath style='font-family:'宋体';v-text-kern:t' trim='t' fitpath='t' string='" + pie[i]*100 + "%'/>");
document.writeln("<o:extrusion v:ext='view' backdepth='8pt' on='t' lightposition='0,0' lightposition2='0,0'/>");
document.writeln("</v:shape>");
document.writeln("</div>");
k1 = k1+k2*2;
if (k1 >= 360)
{
k1 = k1-360;
}
if (k1 > 180)
{
k4 = k4+1;
}
else
{
k4 = k4-1;
}
}
}
function begin(path, width, height, title, unit)
{
stat_array[0] = new Array();
stat_array[1] = new Array();
var str = readFile(path);
var strArray = new Array();
var regExp = /\s+/g;
var len = 0;
strArray = str.split(regExp);
for (i=0; i<strArray.length/2; i++)
{
stat_array[1][i] = strArray[i*2];
stat_array[0][i] = parseInt(strArray[i*2+1]);
}
if (stat_array[0].length > stat_array[1].length)
{
len = stat_array[1].length;
}
else
{
len = stat_array[0].length;
}
table(len,0,0,width,height,title,unit);
}
-->
</SCRIPT>
<script language="vbscript">
<!--
Function bytes2BSTR(vIn)
strReturn = ""
For i = 1 To LenB(vIn)
ThisCharCode = AscB(MidB(vIn,i,1))
If ThisCharCode < &H80 Then
strReturn = strReturn & Chr(ThisCharCode)
Else
NextCharCode = AscB(MidB(vIn,i+1,1))
strReturn = strReturn & Chr(CLng(ThisCharCode) * &H100 + CInt(NextCharCode))
i = i + 1
End If
Next
bytes2BSTR = strReturn
End Function
-->
</script>
</HEAD>
<body>
<script language="javascript">
// 参数说明(数据文件路径,图像宽度,图像高度,图像名称,单位)
begin('text.txt', 700, 400, '初三(1)班期末成绩三维饼状图', '分');
</script>
</body>
</HTML>
-----------------------------------------------------------------------------------------------------------
Text.txt
-----------------------------------------------------------------------------------------------------------
王二 89
张丽 90
黄龙 99
赵云 100
马涛 100
赵力 98
------------------------------------------------------------------------------------------------------------