利用VML实现动态关系图

         前段时间因项目需要实现一个能直观的表达出商品流向的功能。当初考虑了,SVG和VML以及生成图片来显示,因为系统一般在IE下使用,最后采用了VML实现,下面是实现后的几张贴图。

 

 

 由于时间比较仓促只实现了基本功能没有细化,看起来比较粗糙。

       下面主要简述下实现的思路及主要代码,废话不多说代码贴上。

 

 

       线及长方形的显示主要是由几个DTO来描述:

//矩形DTO
public class RectangleDTO {
    private double left;//矩形图左起点
    private double top;//矩形图顶点
    private double width;//矩形宽度
    private String enterpriseName;//图形名称
    private String rectangleColor;//矩形底色
    private String characterColor;//字体颜色
    private double lineX;//从矩形图引出线的X坐标
    private double lineY;//从矩形图引出线的Y坐标
    

    public double getLeft() {
        return left;
    }

    public void setLeft(double left) {
        this.left = left;
    }

    public double getTop() {
        return top;
    }

    public void setTop(double top) {
        this.top = top;
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public String getEnterpriseName() {
        return enterpriseName;
    }

    public void setEnterpriseName(String enterpriseName) {
        this.enterpriseName = enterpriseName;
    }

    public String getRectangleColor() {
        return rectangleColor;
    }

    public void setRectangleColor(String rectangleColor) {
        this.rectangleColor = rectangleColor;
    }

    public String getCharacterColor() {
        return characterColor;
    }

    public void setCharacterColor(String characterColor) {
        this.characterColor = characterColor;
    }

    public double getLineX() {
        return lineX;
    }

    public void setLineX(double lineX) {
        this.lineX = lineX;
    }

    public double getLineY() {
        return lineY;
    }

    public void setLineY(double lineY) {
        this.lineY = lineY;
    }
}
//细化下矩形的点,为线的起始点做准备
public class RectangleAllDTO extends RectangleDTO{
    private double leftX;//矩形框左中点X坐标
    private double leftY;//矩形框左中点Y坐标
    private double rightX;//矩形框右中点X坐标
    private double rightY;//矩形框右中点Y坐标
    
   public double getLeftX() {
        return leftX;
    }

    public void setLeftX(double leftX) {
        this.leftX = leftX;
    }

    public double getLeftY() {
        return leftY;
    }

    public void setLeftY(double leftY) {
        this.leftY = leftY;
    }

    public double getRightX() {
        return rightX;
    }

    public void setRightX(double rightX) {
        this.rightX = rightX;
    }

    public double getRightY() {
        return rightY;
    }

    public void setRightY(double rightY) {
        this.rightY = rightY;
    }

}

//连线的DTO

public class LineDTO {
    private double startX;//起点X坐标
    private double startY;//起点Y坐标
    private double endX;//终点X坐标
    private double endY;//终点Y坐标
    private double controlX;//为绘曲线的控制点X坐标
    private double controlY;//为绘曲线的控制点Y坐标
    private double contentLeft;//内容文字左起点
    private double contentTop;//内容文字顶点
    private String content;//内容文字
    private double contentWidth;//文字宽度
    private double contentHeight;//文字高度
    private String lineColor;//曲线颜色
    private List contentList = new ArrayList();//文字内容列表

    public void addContent(LineContentDTO object){
        this.contentList.add(object);
    }
    public double getStartX() {
        return startX;
    }

    public void setStartX(double startX) {
        this.startX = startX;
    }

    public double getStartY() {
        return startY;
    }

    public void setStartY(double startY) {
        this.startY = startY;
    }

    public double getEndX() {
        return endX;
    }

    public void setEndX(double endX) {
        this.endX = endX;
    }

    public double getEndY() {
        return endY;
    }

    public void setEndY(double endY) {
        this.endY = endY;
    }

    public double getControlX() {
        return controlX;
    }

    public void setControlX(double controlX) {
        this.controlX = controlX;
    }

    public double getControlY() {
        return controlY;
    }

    public void setControlY(double controlY) {
        this.controlY = controlY;
    }

    public double getContentLeft() {
        return contentLeft;
    }

    public void setContentLeft(double contentLeft) {
        this.contentLeft = contentLeft;
    }

    public double getContentTop() {
        return contentTop;
    }

    public void setContentTop(double contentTop) {
        this.contentTop = contentTop;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public double getContentWidth() {
        return contentWidth;
    }

    public void setContentWidth(double contentWidth) {
        this.contentWidth = contentWidth;
    }

    public String getLineColor() {
        return lineColor;
    }

    public void setLineColor(String lineColor) {
        this.lineColor = lineColor;
    }

    public List getContentList() {
        return contentList;
    }

    public void setContentList(List contentList) {
        this.contentList = contentList;
    }

    public double getContentHeight() {
        return contentHeight;
    }

    public void setContentHeight(double contentHeight) {
        this.contentHeight = contentHeight;
    }
}
//线上文字的DTO

public class LineContentDTO {
    private double left;//文字内容左起点
    private double top; //文字内容顶点
    private double width;//文字内容在页面上所占宽度
    private String content;//文字具体内容

    public double getLeft() {
        return left;
    }

    public void setLeft(double left) {
        this.left = left;
    }

    public double getTop() {
        return top;
    }

    public void setTop(double top) {
        this.top = top;
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

 

页面先生成矩形然后在生成连线,矩形的位置和连线的起始点根据自己的业务需求计算出来,这里就不在叙述。页面显示主要代码:

 

<div id="Graph_layer" style="position:absolute;z-index:1; left: 30px; top: 0px;">
            <#list rectangleList as rectangle>
                <v:RoundRect id="_x0000_s00201"
                             style="position:absolute;left:${rectangle.left?string('#.##')}px;top:${rectangle.top?string('#.##')}px;width:${rectangle.width?string('#.##')}px;height:20px;z-index:1"
                             fillcolor="${rectangle.rectangleColor}" strokeweight="1px" strokecolor="#5E80A4"
                             arcsize="0.1">
                    <v:shadow on="T" type="single" color="#b3b3b3" offset="3px,3px"/>
                </v:RoundRect>
                <v:shape inset="0px,0px,0px,0px" id="_x0000_s1025"
                         style="position:absolute;left:${rectangle.left?string('#.##')}px;top:${rectangle.top?string('#.##')}px;width:${rectangle.width?string('#.##')}px;height:30px;z-index:1;text-align:center">
                    <v:textbox><!--  <a οnclick="forward('${rectangle.url}')" href="#" title="点击查看详细信息">--><span
                            class="nameStyle"
                            style="color:${rectangle.characterColor}">${rectangle.enterpriseName}</span></a></v:textbox>
                </v:shape>
            </#list>
            <#list lineList as line>
                <v:rect id="_x0000_s1044"
                        style="position:absolute;left:${(line.startX-3)?string('#.##')}px;top:${(line.startY-3)?string('#.##')}px;width:6px;height:6px;z-index:1"
                        filled="f" strokecolor="#436589"></v:rect>
                <v:rect id="_x0000_s1044"
                        style="position:absolute;left:${(line.endX-3)?string('#.##')}px;top:${(line.endY-3)?string('#.##')}px;width:6px;height:6px;z-index:1"
                        filled="f" strokecolor="#436589"></v:rect>
                <v:curve style="position:absolute;left:0px;top:0px;z-index:1"
                         from="${line.startX?string('#.##')}px,${line.startY?string('#.##')}px"
                         to="${line.endX?string('#.##')}px,${line.endY?string('#.##')}px" filled="f"
                         control1="${line.controlX?string('#.##')}px,${line.controlY?string('#.##')}px"
                         οnclick="javascript:controlCase(this)"
                         strokecolor="${line.lineColor}" strokeweight="1.0px">
                    <v:stroke opacity="1" startarrow="none" endarrow="block" endarrowwidth="medium" endarrowlength="long"/>
                </v:curve>
                <v:rect id="_x0000_s1040"
                        style="position:absolute;left:${line.contentLeft?string('#.##')}px;top:${line.contentTop?string('#.##')}px;width:${line.contentWidth?string('#.##')}px;height:${line.contentHeight?string('#.##')}px;z-index:1"
                        fillcolor="#FFFFFF" stroked="f">
                    <v:fill type="frame" opacity="0.0"/>
                </v:rect>
                <v:shape inset="0px,0px,0px,0px" id="_x0000_s1025"
                         style="position:absolute;left:${line.contentLeft?string('#.##')}px;top:${line.contentTop?string('#.##')}px;width:${line.contentWidth?string('#.##')}px;height:${line.contentHeight?string('#.##')}px;z-index:1;text-align:left">
                    <v:textbox inset="0px,0px,0px,0px"><span class="lineContentStyle">${line.content}</span></v:textbox>
                </v:shape>
            </#list>
        </div>

 上面的是生成图形主要VML代码。在实现的过程中主要是参考了两个教程,下面也贴出来,喜欢的朋友拿去研究研究。

 

   PS:在实现的过程中想把显示的数字放置到线的中点处,探究发现VML中的曲线是贝塞尔曲线,关于更多的贝塞尔曲线可以参考维基百科。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值