VML掠影
我们在开发系统的过程中,有时候需要用图形的方式表现数据,这样可以直观而又清晰地知道数据间的关系以及掌握数据的价值。Web页面上实现绘图的方式有很多,也有很多现成的框架,如JFreeChart、Java
Applet、Javascript绘图组件、Flex等等,但往往会感觉到使用高级语言去动态生成统计图表、实时曲线图时,不但编写起来非常繁琐,而且从美观的角度上讲也是很难设计。有时候感觉太笨重了,绘出来的图像又会失帧,想与客户端交互也非常麻烦,如果想要被搜索引擎检索,那更加感觉到不可能。
项目中,我们尝试了VML矢量标记语言,满足了需求。如图1,展示了页面模板间的关系。
图1 页面模板关系图
一、 VML概述
VML全称Vector Markup Language(矢量标记语言),是微软1999年9月附带IE5.0发布的。它相当于IE里面的画笔,来绘制矢量图形。结合CSS,可以给任何HTML 对象增加新的方法、事件和属性;结合脚本语言,可以让图形产生动态的效果。这种用文本方式描述矢量图形的语言,目标是在Web 上建立高效、灵活和简洁的矢量图形。图2是通过VML绘出的曲线图,可以和客户端实时交互。
图2 VML绘制的曲线图
1.1 VML的优缺点
1、优点
1)基于XML标准
它是基于XML的可用来描述矢量图形的标记语言,因此表示简单,而且易扩展。
2)支持高质量的矢量图形显示
它基于相连接的直线和曲线描述路径。在VML中使用两个基本元素:shape和group。这两个元素定义了VML的全部结构:shape描述一个矢量图形元素,而group用来将这些图形结合起来,使得各图形可以作为一个整体进行处理。
3)由文本构成的图像,并可集成到HTML中
它使用简单的文本来表示图像,这样就可以用很少的字节来表示比较复杂的图像。VML与HTML兼容,通过在HTML中声明VML命名空间和处理函数,就可以和其他HTML元素一样使用VML元素,并在客户端浏览器显示图像。更为方便的是,VML标记里可以定义DHTML大部分属性和事件。
4)可以实现任意想要的形状,轻松实现阴影等效果
它有很多种一级标记和二级标记,可以实现任何想要的形状以及美观效果。只有想不到,没有做不到。
5)支持交互与动画
VML的功能不只是绘图,还可以在图形中嵌入文本,实现超链接,通过脚本实现一定的动画功能。
6)性能
有人将VML和开源的jsgraphics框架进行过比较,得出VML的性能比JavaScript开源框架实现要高30到60倍。JavaScript开源框架实现平均绘制一条线段需要花费8ms,而VML绘制一条线段只需要0.13ms。
2、缺点
1)浏览器局限于IE5.0+。
2)VML是用于客户端的标记语言,所以服务器端代码操作VML元素比较困难。
3)对于如图3这样的不规则图形,需要人工去获得边界的坐标。
4)微软不再更新VML。
图3 VML绘制的中国地图
1.2 VML与GML、SVG的比较
用来描述矢量图形的标记语言除了VML外,还有GML、SVG等,它们都是基于XML的可用来描述矢量图形的标记语言,而且都与矢量图形有着密切的关系。
GML(Geography Markup Language),是基于XML的空间信息编码标准,封装了地理信息及其属性。它在表示实体的空间信息的同时加入了实体的其他属性信息,是表示实体的空间信息和属性的编码标准,但它不支持直接显示图形。
SVG(Scalable
Vector Graphics),是基于XML的开放的矢量图形描述语言,是一种专门为网络而设计的基于文本的图像格式。与VML相比,SVG是综合了VML的优点后推出的,是国际标准,它比VML具有更多的优点,也有更广阔的前景。但由于VML有IE的支持,而SVG要想在浏览器中显示就需要安装插件(Adobe SVG Viewer),正是由于这点,SVG才没有快速的发展起来。
二、 VML的使用
2.1 VML使用三步曲
1)加入VML命名空间
<html
xmlns:v="urn:schemas-microsoft-com:vml">
2)CSS中加入behavior
<style>
v\:*{behavior:url(#default#VML); }
</style>
3)使用VML标记
<v:标记.../>
2.2 标记
1、基本标记
1)shape(任意形状)
示例:创建任意曲线
<v:shape style="width:100;height:100" coordsize="100,100" strokecolor="blue" path="m 0,0 l 100,100 x e"/>
2)line(直线)
示例:创建一条从(0,0)到(200,200)的红色的边框为2px的直线
<v:line strokecolor="red" strokeweight="2" style="z-index:5;position:absolute;left:233;top:150" from="0,0" to="200,200"/>
3)polyline(多边形)
示例:创建不规则的连续线
<v:polyline style="z-index:1;left:71;position:absolute;top:225" points="0,0,30,-40,100,100,0,0" fillcolor="white"/>
4)rect(矩形)、roundrect(圆角矩形)
示例:创建一个宽100高100的矩形
<v:rect style="position:absolute;z-index:1;left:320px;top:150px;width:100;height:100;"/>
5)oval(圆)、arc(圆弧)
示例:创建一个宽400高400边框为红色填充为绿色的圆
<v:Oval strokecolor='red' fillcolor=' green ' style="width:400;height:400"/>
6)curve(曲线)
示例:创建一条曲线
<v:curve style="z-index:1;left:100;position:absolute;top:300" from="0px,0px" to="150px,0px" filled='f' control1="75,150" control2="75,-150"/>
7)background(背景)
<v:background fillcolor="white">
<v:fill angle=50 type='gradient'
color2="yellow"/>
</v:background>
8)image(图像)
值得注意到是,显示从外部调用的图形文件并没有将之矢量化。
<v:image src="demo.jpg" style="position:relative;top:0;left:0;width:165;height:157" />
9)shapetype(模板)
为减少代码的书写量和可读性。用shapetype定义好形状,然后用shape的type属性调用。
示例:定义一个向上的三角形,然后调用它
<v:shapetype id="arrowUP" coordsize="6 6">
<v:path v="m 3,0 l 0,6,6,6,3,0 x e" />
</v:shapetype>
<v:shape type="#arrowUP" style="position:relative;width:50;height:50;left:100;top:100"/>
<v:shape type="#arrowUP" style="position:relative;width:150;height:150; left:200;top:200"/>
10)group(集合容器)
让一些对象成为一个组,拥有共同的坐标系。这样可以动态改变CoordSize的值,来放大或缩小整个Group里面的VML对象。
<v:group id="group1" style=”position:absolute;left:0;top:0;z-index:1;width:100;height:100” coordsize="100,100">
<v:oval style="left:100;top:100;width:50;height:50"
fillcolor="white"/>
<v:rect
style="left:200;top:100;width:50;height:50"
fillcolor="yellow"/>
<v:arc style="left:200;top:200;width:80;height:80"
startangle="360" endangle="167"
fillcolor="blue"/>
</v:group>
2、二级标记
二级标记可以看作是对有限的属性进行扩展,利用它我们可以做出更漂亮的图画出来。
1)fill(填充)
2)stroke(边框)
3)shadow(阴影)
示例:创建一个偏离5像素的阴影
<v:RoundRect style="position:relative;width:100;height:50px">
<v:shadow on="T" type="single" color="#b3b3b3" offset="5px,5px"/>
</v:RoundRect>
4)extrusion(立体3D)
5)textbox(文本)
<v:RoundRect style="position:relative;width:120;height:50px">
<v:TextBox inset="5pt,5pt,5pt,5pt"
style="font-size:10.2pt;">Hello world!</v:TextBox>
</v:RoundRect>
6)imagedata(背景图片)
7)textpath(文本路径)
2.3 属性
1)VML特有的通用属性(HTML、CSS不具有)
属性名 |
默认值 |
值类型/范围 |
用途 |
strokeweight |
0.75pt=1px |
number |
描述图形的边框粗度 |
strokecolor |
black |
color |
描述图形的边框颜色 |
stroked |
true |
boolean |
描述图形是否使用边框 |
fillcolor |
white |
color |
描述图形的背景颜色 |
filled |
true |
boolean |
描述图形是否使用背景 |
print |
true |
boolean |
描述图形是否允许被打印机打印 |
coordsize |
1000,1000 |
Vector2D |
暗示图形与容器空间的大小比例 |
coordorigin |
0, 0 |
Vector2D |
元素的左上角坐标 |
2)VML标记支持的HTML通用属性
属性名 |
默认值 |
值类型/范围 |
用途 |
id |
null |
string |
定义元素的标识索引 |
class |
null |
classname |
定义元素使用的CSS样式类 |
style |
null |
CSS string |
描述图形的CSS样式表 |
title |
null |
string |
定义图形的提示标题 |
href |
null |
string |
定义图形链接的URL地址 |
target |
_self |
_self/_blank/_top |
定义图形以何种形式打开链接 |
contentEditable |
false |
boolean |
描述图形内容是否允许用户编辑 |
dir |
ltr |
ltr/rtl |
描述图形内容以哪种方向输出 |
disabled |
false |
boolean |
描述图形能够响应用户事件触发 |
|
|
|
|
3)VML标记支持的CSS通用属性
属性名 |
可用值/可用值范围 |
用途 |
width |
0-9999 |
描述宽度 |
height |
0-9999 |
描述高度 |
position |
static/absolute/fixed/relative |
描述如何定位输出 |
left |
0-9999 |
描述距离页面位置左 |
top |
0-9999 |
描述距离页面位置上 |
z-index |
0-9999 |
描述3D位置 |
cursor |
auto/crosshair/hand/move/help/wait/
text/… |
描述鼠标形状 |
zoom |
0-99 |
描述缩放比例 |
clip |
rect(上
右
下
左) |
描述裁剪对象 |
border |
0-99 |
描述边框 |
display |
block/none/inline/list-item |
描述显示或隐藏 |
overflow |
visible/auto/hidden/scroll |
描述滚动条 |
color |
colorstring |
描述文本内容颜色 |
font-size |
0-999 |
描述文本内容字号 |
filter |
xray/flipv/fliph/invert/alpha(opacity=num) |
描述滤镜效果 |
rotation |
(0-9999)%360 |
描述旋转度 |
flip |
x y |
描述反转或颠倒图形 |
三、 更多参考
1、http://www.w3.org/TR/NOTE-VML
2、http://msdn.microsoft.com/en-us/library/bb263898(VS.85).aspx
3、http://www.w3.org/Graphics/SVG/
ps:本篇文章写于2009年12月,目前VML基本要淘汰了,HTML5的canvas可以代替之