利用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
------------------------------------------------------------------------------------------------------------

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 
<!--
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                               ┃
┃ 摘 要: 统计图--饼图                     ┃
┃ 作 者: 无涯                          ┃
┃ 创建日期: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 
= "&nbsp;名&nbsp;&nbsp;称:" + stat_array[1][i] + " &nbsp;数&nbsp;&nbsp;值:" + stat_array[0][i] + unit + " &nbsp;所占比例:" +  pie[i]*100 + "%&nbsp;&nbsp;"
    
     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', 700400, '初三(1)班期末成绩三维饼状图', '分');   
  
</script>
 
</body>
</HTML>


-----------------------------------------------------------------------------------------------------------
Text.txt
-----------------------------------------------------------------------------------------------------------
王二  89
张丽  90
黄龙 99
赵云 100
马涛 100
赵力 98
------------------------------------------------------------------------------------------------------------

posted @ 2006-03-02 10:36  无涯  阅读(13447)  评论(28编辑  收藏  举报

开源代码搜索引擎: