vml是什么,大家自己baidu、google
vml.zip
下图为用vml在IE浏览器下实现的效果图

ellipserVML.js
//点的对象:
function point(x0,y0)
{
    this.x = x0;
    this.y = y0;
    //向量的模
    this.r = Math.sqrt(this.x*this.x+this.y*this.y);
    //反余弦函数,反函数的返回数值的单位都为弧度(比如 PI弧度=180度),其中余弦函数cos = x/r
    var alfa = Math.acos(this.x/this.r);
    if (this.y >= 0) {
        alfa = alfa;
    } else {
        alfa = 2*Math.PI-alfa;
    }
    //向量的倾角(弧度)
    this.alfaR = alfa;
    //向量的倾角(角度)
    this.alfaD = alfa*180/Math.PI;
}
//画线条
//id:对象ID;from:起点;to:终点;strokeweight:线条磅数;txt:标注;dashstyle:线条样式;arrow1:起点鼠标样式;arrow2:终点鼠标样式
function lineing(id,from,to,strokeweight,strokecolor,txt,dashstyle,arrow1,arrow2) {
    this.id = id;
    this.from = from;
    this.to = to;
    if (strokeweight==undefined)
    {
        strokeweight = "1";
    }
    if (strokecolor==undefined)
    {
        strokecolor = "#00F";
    }
    //dashstyle= Solid,ShortDash,ShortDot,ShortDashDot,ShortDashDotDot,Dot,Dash,LongDash,DashDot,LongDashDot,LongDashDotDot
    if (dashstyle==undefined)
    {
        dashstyle = "solid";
    }
    //arrow=None,Block,Classic,Diamond,Oval,Open
    if (arrow1==undefined)
    {
        arrow1 = "";
    }
    if (arrow2==undefined)
    {
        arrow2 = "Classic";
    }
    if (txt==undefined)
    {
        txt = "";
    }
    this.strokeweight = strokeweight;
    this.strokecolor = strokecolor;
    this.dashstyle = dashstyle;
    this.startarrow = arrow1;
    this.endarrow = arrow2;
    this.txt = txt;
    //设置线条的长度
    this.length = getlinelen;
    //画线
    this.draw = drawline;
}
 
//取得线段的长度:
function getlinelen()
{
    if ((this.from.x == this.to.x) && (this.from.y == this.to.y))
    {
        return 0;
    } else
    {
        return Math.sqrt((this.from.x-this.to.x)*(this.from.x-this.to.x)+(this.from.y-this.to.y)*(this.from.y-this.to.y));
    }
}
 
//画线函数   
function drawline()
{
    var str = "";
    //画线条
    str = str +"<v:line id=line"+this.id+" style='position:absolute;left:0;top:0;z-index:2' ";
    str = str +" from='"+this.from.x+","+this.from.y+"'";
    str = str +" to='"+ this.to.x +","+ this.to.y +"' ";
    str = str +" strokeweight='"+this.strokeweight+"px;' strokecolor='"+this.strokecolor+"'> ";
    str = str +" <v:stroke dashstyle='"+this.dashstyle+"' startarrow='"+this.startarrow+"' endarrow='"+this.endarrow+"' /> ";
    str = str +"</v:line>";
   
    //画线条文字
    if(this.txt != "")
    {
        //因为水平线或垂直线输出的文本只有一条线,所以让坐标偏移1个像素;
        if(this.from.x == this.to.x)
        {
            this.to.x += 1;
        }
        if(this.from.y == this.to.y)
        {
            this.to.y += 1;
        }
       
        str = str +"<v:line style='position:absolute;left:0;top:0;z-index:3;' from='"+this.from.x+","+this.from.y+"'";
        str = str +" to='"+ this.to.x +","+ this.to.y +"'>";
        str = str + "  <v:path textpathok='t'/>";
        str = str + "  <v:textpath id=linetext"+this.id+" style='font-size:12px;' on='t' fitpath='f' string='" +this.txt+"' />";
        str = str +"</v:line>";
    }
    document.write(str);
}
// 画椭园:
function ellipsering(id,x0,y0,ra,rb,filled,fillcolor,stroked,strokecolor,strokeweight,rotation,txt, url)
{
    if(id == '')
    {
        id = txt;
        url = '';
    }
    this.id = id;
    this.x = x0;
    this.y = y0;
    this.ra = ra;
    this.rb = rb;
    this.eleft = x0-ra;
    this.etop = y0-rb;
    this.ewidth = 2*ra;
    this.eheight = 2*rb;
    this.filled = filled;
    this.fillcolor = fillcolor;
    this.stroked = stroked;
    this.strokecolor = strokecolor;
    this.strokeweight = strokeweight;
    this.rotation = rotation;
    this.txt = txt;
    if (url==undefined)
    {
        url = "";
    }
    this.url = url;
   
    this.draw = drawEllipser;
}
//画椭圆函数   
function drawEllipser()
{
    var str = "";
    str = str +"<v:oval id="+this.id+" ";
    str = str +" style='position:absolute; ";
    str = str +" left:"+this.eleft+";top:"+this.etop+";width:"+this.ewidth+";height:"+this.eheight+"; ";
    str = str +" rotation:"+this.rotation+"fd;z-index:1' ";
    //str = str +" onmousedown='down1(this);'";
    str = str +" filled='"+this.filled+"' fillcolor="+this.fillcolor+" stroked='"+this.stroked+"' strokecolor="+this.strokecolor+" ";
    str = str +" strokeweight="+this.strokeweight+"> ";
    str = str +" <v:fill type='gradient' color2='white' angle='180'></v:fill>";
    str = str +" <v:stroke dashstyle='solid'/>";
    //str = str +"  <v:TextBox inset='0,0,0,0'><p style='font-size:12px;' align=center>"+this.txt+"</p></v:TextBox>";
    str = str + "  <div style='font-size:12px; text-align:center; width:"+this.ewidth+"px; height:"+this.eheight+"px; line-height:"+this.eheight+"px;overflow:hidden;' title='" + this.txt +"'>";
    if(this.url == '')
        str = str + top(this.txt,6);
    else
        str = str + "<a href='" + this.url + "' target='_blank'>" + top(this.txt,6) + "</a>";
    str = str + "  </div>";
    //str = str + "  <div style='font-size:12px; text-align:center; width:100%; height:100%; line-height:100%;overflow:hidden;'>"+this.txt+"</div>";
    str = str +"</v:oval>";
   
    document.write(str);
}
//椭圆a,b中心连线,除椭圆a部分线条:
function DisPnt(a,b)
{
    var ab = new point(b.x-a.x,b.y-a.y);
    var x2 = a.x + a.ra * Math.cos(ab.alfaR);
    var y2 = a.y + a.rb * Math.sin(ab.alfaR);
    return new point(x2,y2);
}
 
//画两椭圆间的连接线(不是通过圆心,而是通过圆周)
//一个椭圆a,另一个椭圆b
function Line2Cir(id,a,b,clr,txt)
{
     a1 = new DisPnt(a,b);
     b1 = new DisPnt(b,a);
     var lab1 = new lineing(id,a1,b1,1,clr,txt);
     lab1.draw();
     return;
}
//截取str字符串前num个字符串
function top(str, num)
{
     if(str.length > num)
          str = str.substring(0, num-1)+'…';
     return str;
}
ellipserVML2.js
var R=25, marginTop = 50, levelSpan = 100, maxWidth = 800, curZoom=1;
var qyUrl = "qy.jsp?DM=";
var personUrl = "person.jsp?IDCard=";
function paintRelations(){
    this.pNodes = new Array();          // 节点信息
    this.levels = new Array();          // 层信息
    this.lines = new Array();           // 连线信息
    this.draw = drawPic;             // 画图
    //id:对象ID;name:显示文本;ntype:0表示个人,1表示企业;level:显示在第几层;isnormal:是否有问题;
    this.addPNode = function (id,name,ntype, level,isnormal)
    {
        //如果ID为空,则将ID置为NAME
        if(id == "")
        {
            id = name;
        }
       
        for(var j=0; j<this.pNodes.length; j++)
        {
            if(this.pNodes[j].id == id)
                return;
        }
        var pnode = new Object();
        pnode.id = id;
        pnode.name = name;
        pnode.ntype = ntype;
        pnode.level = level;
        pnode.isnormal = isnormal;
        var i = 0;
        for(i=0; i<this.levels.length; i++)
        {
            if(this.levels[i].level == level)
            {
                this.levels[i].nodeArr = this.levels[i].nodeArr + "," + this.pNodes.length;
                break;
            }
        }
        if(i == this.levels.length)
        {
            var levelObj = new Object();
            levelObj.level = level;
            levelObj.nodeArr = "" + this.pNodes.length;
            this.levels[this.levels.length] = levelObj;
        }
        //零层节点不加链接,id=name的节点也不加链接
        if(id == name || level==0)
            pnode.url = '';
        else if(pnode.ntype == 1)
            pnode.url = qyUrl+id;
        else
            pnode.url = personUrl+id;
        //添加椭圆对象至节点
        //pnode.ellipser = obj;
        this.pNodes[this.pNodes.length] = pnode;
    }
    //id1:对象1ID;name1:对象1name;id2:对象2ID;name2:对象2name;d:方向; txt:标注;
    this.addLine = function(id1, name1, id2, name2, d, txt)
    {
        //如果ID为空,则将ID置为NAME
        if(id1 == "")
        {
            id1 = name1;
        }
        if(id2 == "")
        {
            id2 = name2;
        }
        var lineObj = new Object();
        var obj1, obj2;
        for(var j=0; j<this.pNodes.length; j++)
        {
            if(this.pNodes[j].id == id1)
                obj1 = this.pNodes[j];
            if(this.pNodes[j].id == id2)
                obj2 = this.pNodes[j];
        }
       
        if(d == undefined)
        {
            d = 0;
        }
        if(d == 0)
        {
            lineObj.from = obj1;
            lineObj.to = obj2;
        }
        else
        {
            lineObj.from = obj2;
            lineObj.to = obj1;
        }
        lineObj.txt = txt;
        this.lines[this.lines.length] = lineObj;
    }
}
//画线函数
function Line2Node(i, a, b, txt)
{
    Line2Cir(i,a.ellipser,b.ellipser,"#777", txt);
}
//画图
function drawPic()
{
    //根据层,画所有的节点
    for(var j=0; j<this.levels.length; j++)
    {
        var level = this.levels[j].level;
        var levelNodeArr = this.levels[j].nodeArr.split(",");
        var y = marginTop + levelSpan * level;
        for(var i=0; i<levelNodeArr.length; i++)
        {
            var pnode = this.pNodes[levelNodeArr[i]];
            var x = maxWidth*(i+1)/(levelNodeArr.length+1);
            var ra = R;
            if(pnode.ntype == 1)//如果是企业,则用椭圆显示
            {
                ra = 3*R/2;
            }
            var rb = R;
            var filledColor = "#00ff00";
            if(pnode.isnormal == 0) //有问题企业或个人
            {
                filledColor = "#ff0000";
            }
            var obj = new ellipsering(pnode.id, x, y, ra, rb, "t",filledColor, "t", "#FF0000",-1,"0,0", pnode.name, pnode.url);
            obj.draw();
            //添加椭圆对象至节点
            pnode.ellipser = obj;
        }
    }
   
    //画所有的连线
    for(var j=0; j<this.lines.length; j++)
    {
        var lineObj = this.lines[j];
        Line2Node(j, lineObj.from, lineObj.to, lineObj.txt)
    }
}
//放大缩小函数
function zoom(val)
{
 var zoomval = 0.1;
 if(val=="zoomin")
 {
  zoomval = 1-zoomval;
 }
 else
 {
  zoomval = 1+zoomval;
 }
 curZoom = curZoom*zoomval;
    var obj = document.getElementById("group1");
    obj.coordsize = 800/curZoom+","+800/curZoom;
    for(var i=0;i<document.all.tags("div").length;i++)
    {
      var swidth = document.all.tags("div").item(i).style.width;
      var dwidth = swidth.substring(0, swidth.length-2);
      document.all.tags("div").item(i).style.width = (dwidth*zoomval) + "px";
     
      var sheight = document.all.tags("div").item(i).style.height;
      var dheight = sheight.substring(0, sheight.length-2);
      document.all.tags("div").item(i).style.height = (dheight*zoomval) + "px";
      document.all.tags("div").item(i).style.lineHeight = (dheight*zoomval) + "px";
      document.all.tags("div").item(i).style.fontSize= (12*curZoom) + "px";
    }
   
    for(var i=0; i<a.lines.length; i++)
    {
        var obj = document.getElementById("linetext"+i);
        obj.style.fontSize= (12*curZoom) + "px";
    }
}
test.html
<html xmlns:v>
<style>
v\:*{behavior:url(#default#VML);}
</style>
<script language='javascript' type="text/javascript" src="ellipserVML.js"></script>
<script language='javascript' type="text/javascript" src="ellipserVML2.js"></script>
<body>
<div id="tt"></div>
<table width="800" cellpadding="0" cellspacing="0" border="1" align="center">
<tr>
<td>
<v:group id="group1" style="width:800; height:800;" coordsize="800,800">
<script>
var a = new paintRelations();
//id:对象ID;name:显示文本;ntype:0表示个人,1表示企业;level:显示在第几层;isnormal:是否有问题;
a.addPNode("aa", "张三", 0, 0, 0);
a.addPNode("bb", "企业B", 1, 1, 0);
a.addPNode("oo", "企业C", 1, 1, 0);
a.addPNode("dd", "企业D", 1, 1, 0);
a.addPNode("ee", "李四", 0, 2, 1);
a.addPNode("ff", "企业F", 1, 2, 1);
a.addPNode("gg", "王五", 0, 2, 1);
a.addPNode("xx", "root", 0, 3, 2);
a.addPNode("mm", "child", 0, 4, 2);
//id1:对象1ID;name1:对象1name;id2:对象2ID;name2:对象2name;d:方向; txt:标注;
a.addLine("aa", "张三", "bb", "企业B", 0, "投资");
a.addLine("aa", "张三", "oo", "企业C", 0, "投资");
a.addLine("aa", "张三", "dd", "企业D", 0, "法人");
a.addLine("oo", "张三", "ff", "企业D", 0, "法人");
a.addLine("bb", "企业", "ee", "李四", 0, "投资");
a.addLine("bb", "企业", "ff", "企业F", 0, "投资");
a.addLine("dd", "企业", "gg", "企业F", 0, "投资");
a.addLine("dd", "企业", "gg", "企业F", 0, "投资");
a.addLine("xx", "企业", "mm", "企业F", 0, "理财");
a.addLine("ee", "企业", "mm", "企业F", 0, "理财");
a.addLine("ff", "企业", "xx", "企业F", 0, "理财");
a.addLine("xx", "企业", "mm", "企业F", 0, "理财");
a.addLine("gg", "企业", "mm", "企业F", 0, "理财");
a.addLine("dd", "企业", "ff", "李四", 0, "投资");
a.draw();
</script>
</v:group>
</td>
</tr>
</table>
<center>
<input type="button" name="zoominBut" value="缩小" onclick="zoom('zoomin');"/><input type="button" name="zoomoutBut" value="放大" onclick="zoom('zoomout');"/>
</center>
</body>
</html>
vml.zip