利用vml制作统计图全攻略.doc_第1页
利用vml制作统计图全攻略.doc_第2页
利用vml制作统计图全攻略.doc_第3页
利用vml制作统计图全攻略.doc_第4页
利用vml制作统计图全攻略.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

VIP免费下载

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

利用vml制作统计图全攻略作者:蓝翼 CSDN账号:liuruhong(蓝色街灯)电子邮件: MSN: blueswing_ 关键字: VML Javascript OOP 统计图提要: VML是Microsoft IE 5.0及其后续版本内嵌的矢量图形实现,虽然MS也提倡日后使用SVG,但是作为一个IE内嵌的标记语言,在某些时候的应用还是比较方便的。本文通过完整的描述一个统计饼图的建立过程,来展现VML在Web方面的魅力。文章通过实现一个JavaScript类,读者能够完整地看到整个饼图的制作过程。 VML(Vector Markup Language)自从问世以来似乎都处于默默无闻的地步,直到现在为止,情况依然没有改变。其实细心的一点你就可以发现,在Web方面,MS得很多产品还是内置使用了,最典型的就是Office的自选图形,将word或者ppt文档存储成html,如果文档内部使用了自选图形,你就可以看到那些图形使用过VML来表述的,另外一个典型的应用就是Visio的导出到web这个工具。 前段时间,James在CSDN发表了使用ASP生成统计图的例子,我也认真拜读了其中的代码,并且也针对一些问题找他请教了,James的颜色感觉非常好,可惜我没有那样的功底,因此在代码实现中我就使用了随机颜色来实现,可能整体的界面看起来会稍微差劲一点。 统计图比较典型的是饼图,柱状图,曲线图,本文着重讲解Pie的制作过程,文章采用了JavaScript实现了一个类,如果相关Javascript面向对象不是特别了解的,可以参考我另外的文章面向对象的Javascript编程和再论面向对象的JavaScript编程。 暂且不考虑如何实现,我们先看看代码最终的使用如何。 objPie=new VMLPie(600px,450px,人口统计图); /初始化宽度,高度,标题 objPie.BorderWidth=3; /图表边框 objPie.BorderColor=blue; /图表边框颜色 objPie.Width=800px; /定义图表宽度 objPie.Height=600px; /定义图表高度 objPie.backgroundColor=#ffffff; /定义背景颜色 objPie.Shadow=true; /是否需要阴影 true为是 false为不要阴影 /添加图表数据 /顺序为名称,值,描述 objPie.AddData(北京,50,北京的人口); objPie.AddData(上海,52,上海的固定人口); objPie.AddData(天津,30,天津的外地人口); objPie.AddData(西安,58,西安城市人口); objPie.AddData(武汉,30,武汉的外地人口); objPie.AddData(重庆,58,重庆城市人口); result.innerHTML=objPie.Draw(); /生成VML数据 这段代码就是最终的调用,我封装了一个VMLPie的JavaScript类,而本文的重点也就是详细地描述类的具体实现过程,另外要使用VML必须作如下的声明。1 HTML Tag的名字空间声明2 之间的style声明 v:* BEHAVIOR: url(#default#VML) o:* BEHAVIOR: url(#default#VML) .shape BEHAVIOR: url(#default#VML) 完成了上述工作之后,代码就能够完整的工作了。现在我们开始讲述这个VMLPie的实现了,首先,我将那些实现的函数作一个简单的说明。/VMLPic主函数,提供创建一个VMLPie实例function VMLPie(pWidth,pHeight,pCaption,pContainer)/开始画图,将图形画到指定的容器上面VMLPtotype.Draw=function()/画饼图的各个块VMLPtotype.CreatePie=function()/接口功能:/ 放大或者缩小图形/参数说明:/ iValue:放大的或者缩小的倍数,1为原图大小,0.5原图的50%,2为原图的/ 两倍,以此类推VMLPtotype.Zoom=function (iValue)/接口功能:/ 添加饼图数据/参数说明:/ sName:数据标签名称/ sValue:数据值/ sTooltipText:数据描述VMLPtotype.AddData=function(sName,sValue,sTooltipText)/接口功能:/ 清除所有数据VMLPtotype.Clear=function()/以下四个函数是扩展使用,就是提供一些VML的交互function HoverPie(el)function RestorePie(el)function LegendMouseOverEvent()function LegendMouseOutEvent()看完这些函数的说明,我想读者对于整个类的结构有一个大致的想法思路了吧,可是对于VML的制作,可能还是没有一个很清晰的思路吧,那么,下面我就着重介绍几个VML元素,我只是大致的介绍一些用法,具体的在 美洲豹的 VML中文教程有比较详细地介绍,如果有兴趣的话可以去参考参考。1. V:Group作为VML其它元素的容器,其属性coordsize定义其坐标大小,内部的元素的位置都只是相对于group元素所定义的coordsize,假设coordsize定义为21600,21600,就是定义了21600 * 21600的画布,如果内部有一个v:shape或者其它元素, shape.style.left=”2160px”,其实际位置只是在v:group的1/10宽度的位置。2. V:Rect定义一个矩形元素,fillcolor表示填充的背景颜色,stokecolor表示边框颜色,strokeweight表示边框宽度3. V:ShapeVML提供的默认形状元素,通过定义path可以定义出需要的任何形状,至于path的用法,可以参考w3c的文档。4. V:Fill作为shape的子元素,用来设置shape的背景效果,通过type来设置填充的方法,具体用法如下1) solid:实心填充,通过color设置填充颜色2) gradient:线状渐变,这个时候需要color和color2这两个参数来设置渐变的开始颜色和结束颜色,Angle则设置渐变方向。3) gradientradial:圆心渐变,其他的使用方法和gradient类似4) tile:使用图片平铺,src设置图片5) pattern:使用图片作为一个图章填充模式6) frame:使用图片拉神填充 另外Opacity则用来设置透明度5. V:Shadow设置shape是否需要阴影,主要使用如下参数ON:设置是否启用阴影Color:阴影的颜色Offset:阴影的偏离位置6. V:TextBox定义shape的文字区域以上的这些元素是我在制作VMLPie需要使用到的,所以做了一个简单的介绍,具体的可以参考豹子的VML中文教程,另外MSDN里头的Vector Markup Language(VML)的SDK Document是一个非常好的参考资料。W3c的note比较抽象,在做一些比较深入的开发的时候,也是一个非常重要的参考。利用vml制作统计图全攻略-饼图的制作 (二)做完了一系列的准备工作,那么现在应该开始真正介绍如何绘制Pie了吧。首先看看下面的一个示意图,清楚地描述了VMLPie的元素结构。为了更加清楚的显示构成VML的文本结构,我使用XML的格式给出了如下的方式。 VML饼图 重庆(50) 完成了制图的基本思路之后,剩下的就是通过DOM逐步完成建立过程了,为了简单起见,我们安装函数的功能进行逐步分析。1 VMLPie this.Container=pContainer; this.Width= pWidth | 400px; this.Height=pHeight | 250px; this.Caption = pCaption | VML Chart; this.backgroundColor=; this.Shadow=false; this.BorderWidth=0; this.BorderColor=null; this.all=new Array(); this.id=document.uniqueID; this.RandColor=function() return rgb(+ parseInt( Math.random() * 255) +, +parseInt( Math.random() * 255) +, +parseInt( Math.random() * 255)+); this.VMLObject=null; this.LegendObject=null;这个函数只是简单的初始化了一些变量,将class可以使用的一些属性在这里做了声明。RandColor函数提供了生成随机颜色的作用,这个也就是我在前文提到的,对于饼图的各个块的颜色,我都采用随机颜色,这样带来的一个问题就是会出现有些时候两个颜色比较接近,如果随能够给我提供几个基础的颜色列表,我将感激不尽。2 VMLPtotype.AddData添加图表数据,在这里我采用了prototype滞后加载的方式实现,如果读者认为这样不够清晰,可以修改成this.RandColor那样的内置形式。实现代码如下:VMLPtotype.AddData=function(sName,sValue,sTooltipText) var oData=new Object(); oData.Name=sName; oData.Value=sValue; oData.TooltipText=sTooltipText; var iCount=this.all.length; this.alliCount=oData;这里使用一个Object来存储每一个数据项,然后放到this.all这个数组中。3 VMLPtotype.Draw整个类实现最关键的函数,也就是在这个函数和后续的CreatePie函数中,一步一步地实现了图形的绘制工作。/画外框var o=document.createElement(v:group);o.id=this.id;o.style.width=this.Width;o.style.height=this.Height;o.coordsize=21600,21600;/添加一个背景层var vRect=document.createElement(v:rect);vRect.style.width=21600pxvRect.style.height=21600pxo.appendChild(vRect);/添加标题 var vCaption=document.createElement(v:textbox);vCaption.style.fontSize=24px; vCaption.style.height=24pxvCaption.preSize=24;vCaption.style.fontWeight=bold;vCaption.innerHTML=this.Caption;vCaption.style.textAlign=center;vRect.appendChild(vCaption);/设置边框大小 if(this.BorderWidth) vRect.strokeweight=this.BorderWidth;/设置边框颜色if(this.BorderColor) vRect.strokecolor=this.BorderColor;/设置背景颜色if(this.backgroundColor) vRect.fillcolor=this.backgroundColor;/设置是否出现阴影if(this.Shadow) var vShadow=document.createElement(v:shadow); vShadow.on=t; vShadow.type=single; vShadow.color=graytext; vShadow.offset=4px,4px; vRect.appendChild(vShadow);this.VMLObject=o;完成上述工作之后,已经构建出了一个canvas(画布),完成了图形外框及其标题的制作,剩下的也就是最最重要的工作调用CreatePie来画出各个块,并且作出图例。IMGA/IMGA利用vml制作统计图全攻略-饼图的制作 (三)4 VMLPtotype.CreatePieCreatePie提供了一个参数,也就是饼图制作的容器,我们通过Draw的上述代码已经建立了一个V:Group元素,这个也就是饼图绘制的容器了。var mX=Math.pow(2,16) * 360;/这个参数是划图形的关键/AE x y width height startangle endangle/x y表示圆心位置/width height形状的大小/startangle endangle的计算方法如下/ 216 * 度数 var vTotal=0;var startAngle=0;var endAngle=0;var pieAngle=0;var prePieAngle=0; /计算数据的总和for(i=0;ithis.all.length;i+) vTotal+=this.all.Value;/建立图例容器/这里子元素的left,top或者width都是针对于容器设置的坐标系统而言的/例如/图表容器我设置了coordsize为 21600,21600,那么objLengendGroup的位置都是相对于这个坐标系统而言的/和实际图形显示的大小没有直接关系var objLegendGroup=document.createElement(v:group);with(objLegendGroup) style.left=17000px; style.top=4000px; style.width=4000px; style.height=1400 * this.all.length +px; coordsize=21600,21600; /做图例的背景填充并且设置阴影var objLegendRect=document.createElement(v:rect);objLegendRect.fillcolor= #EBF1F9;objLegendRect.strokeweight=1;with(objLegendRect) /设置为21600,21600,就是保证完全覆盖group客户区 style.width=21600px; style.height=21600px; /对于图例加入阴影var vShadow=document.createElement(v:shadow);vShadow.on=t; vShadow.type=single;vShadow.color=graytext;vShadow.offset=4px,4px; objLegendRect.appendChild(vShadow);/将其放到图例的容器中objLegendGroup.appendChild(objLegendRect);this.LegendObject=objLegendGroup;vGroup.appendChild(objLegendGroup);这个时候,我们已经完成了各个区域位置的绘制,通过如上的代码,我绘制了一个LegendGroup,将其作为图例的显示位置,另外主的V:group就作为pie的绘制容器,如果出于规范的考虑,也应该将Pie的各个shape放到一个group中,那样在日后的编程控制中会更加方便一点。下面的这段代码也就是我要讲述的,因为代码比较关键,除了给出代码,我还着重的说明各个语句的作用。for(i=0;ithis.all.length;i+) /顺序的划出各个饼图 var vPieEl=document.createElement(v:shape); var vPieId=document.uniqueID; vPieEl.style.width=15000px; vPieEl.style.height=14000px; vPieEl.style.top=4000px; vPieEl.style.left=1000px; vPieEl.adj=0,0; vPieEl.coordsize=1500,1400; vPieEl.strokecolor=white; vPieEl.id=vPieId; vPieEl.style.zIndex=1; vPieEl.onmouseover=HoverPie(this); vPieEl.onmouseout=RestorePie(this); pieAngle= this.all.Value / vTotal; startAngle+=prePieAngle; prePieAngle=pieAngle; endAngle=pieAngle; vPieEl.path=M 750 700 AE 750 700 750 700 + parseInt(mX * startAngle) + + parseInt(mX * endAngle) + xe; vPieEl.title=this.all.Name +n所占比例:+ endAngle * 100 +%n详细描述: +this.all.TooltipText; vPieEl._scale=parseInt( 360 * (startAngle + endAngle /2); var objFill=document.createElement(v:fill); objFill.rotate=t; objFill.focus=100%; objFill.type=gradient; objFill.angle=parseInt( 360 * (startAngle + endAngle /2); var objTextbox=document.createElement(v:textbox); objTextbox.innerHTML=this.all.Name +: + this.all.Value; objTextbox.inset=5px 5px 5px 5px; objTextbox.style.width=100px; objTextbox.style.height=20px; var vColor=this.RandColor(); vPieEl.fillcolor=vColor; /设置颜色 /开始画图例 p.innerText=vPieEl.outerHTML; var colorTip=document.createElement(v:rect); var iHeight=parseInt(21600 / (this.all.length * 2); var iWidth=parseInt(iHeight * parseInt(objLegendGroup.style.height) /parseInt(objLegendGroup.style.width) /1.5 ); colorTip.style.height= iHeight; colorTip.style.width=iWidth; colorTip.style.top=iHeight * i * 2 + parseInt(iHeight /2); colorTip.style.left=parseInt(iWidth /2); colorTip.fillcolor=vColor; colorTip.element=vPieId; /colorTip.attachEvent(onmouse,LegendMouseOverEvent); colorTip.onmouseover=LegendMouseOverEvent(); colorTip.onmouseout=LegendMouseOutEvent(); var textTip=document.createElement(v:rect); textTip.style.top=parseInt(colorTip.style.top)- 500; textTip.style.left= iWidth * 2; textTip.innerHTML= + this.all.Name +(+ this.all.Value+); objLegendGroup.appendChild(colorTip); objLegendGroup.appendChild(textTip); vGroup.appendChild(vPieEl); 利用vml制作统计图全攻略-饼图的制作(四)我们现在就开始来看如上代码的实现。1. 首先建立一个v:shape,left,top,width,height分别设置为1000px,4000px,15000px;14000px;这个的数字是我根据大致的位置确定的。2. 设置每个shape的id,我采用了document.uniqueID,就是用DOM的方法提供的随机id,本来我没有打算设置这个ID,但是后来考虑到和legend的交互,所以就设置了每个shape的ID.3. 设置shape的onmouseover,onmouseout事件,开始的时候我是采用attachEvent的方式来实现的,后来发现无法起作用(到现在我也没有找到原因),求出每个数据所占的比例。4. 设置Path,这个也就是比较令人难以看懂的部分了,我首先求出了startAngle和endAngle,startAngle的意义是这样的,假设有3个数,0.2,0.2,0.4,对于第二项来说,startAngle应该是 0.25,endAngle是0.25,对于第三项来说,startAngle是0.5,endAngle是0.5,总而言之,startAngle可以表示为前面数据所占的比例,engAngle表示当前数据所占的比例。Path有很多指令,对于其他指令,我就不多作解释,而这里使用的是M 750 700 AE 750 700 750 700 start end 。对于shape我重新定义了coordsize=”1500,1400”,m 750,700则表示移动到 750,700,就是移动到shape定义的中心,AE用来画曲线,总共有6个参数,w3c的note描述如下center (x,y) size(w,h) start-angle, end-angle,前面四个参数不难理解,剩下的两个参数我不是特别明白意思,但是在国外的一篇文章看到其中的算法如下应该是 216 * 度数,对应于程序,就应该是startAngle * 216 * 360,因为我的startAngle是比例。5. 通过设置fillcolor来设置饼图块的颜色,同时设置title提供一些提示信息.6. 对于图例开始着色,同时添加图例的文字说明.7. 因为所有的坐标系统都是相对的,为了保证美观,对于objLegendGroup我通过1400 * this.all.length +px来求得,而对于图例的colortip,高度和宽度就是动态计算的。到目前为止,通过程序已经建立了一个基于VML的Pie,剩下的就是输出的问题了,前文我也提到过,我通过DOM方式建立的VML在显示方面没有任何问题,可是在动态交互方面,似乎不起作用,obj.VMLObject就是一个DOM对象,可是对于onmouseover,onmouseout等等的设置如果直接使用appendChild的方式的时候,根本无法起作用。而通过设置innerHTML来生成VML图形的时候,那些鼠标事件却可以响应,有过这个方面编程的朋友麻烦告诉我具体的原因如何。function HoverPie(el)function RestorePie(el)function LegendMouseOverEvent()function LegendMouseOutEvent()这四个函数就是提供了简单的交互作用。具体的代码如下:function HoverPie(el) var v_length=500; var x_cur=Math.cos( el._scale * Math.PI /180); var y_cur=Math.sin (el._scale * Math.PI /180); x=parseInt(x_cur *v_length); y=parseInt(y_cur * v_length); el.style.top=4000 -y; el.style.left=1000 +x; el.strokecolor=black;function RestorePie(el) el.style.top=4000; el.style.left=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论