Mxgraph.js使用(一)、

一、Mxgraph介绍:

       mxGraph 是一个 JS 绘图组件适用于需要在网页中设计/编辑 Workflow/BPM流程图、图表、网络图和普通图形的 Web 应用程序。mxgraph 下载包中包括javescript 写的前端程序,也包括多个和后端程序(java/C#等等)集成的例子。

       git开源项目地址:https://github.com/jgraph/mxgraph

  mxGraph资源包及其例子可下载地址:mxGraph下载

  解压并打开mxGraph\devel\source\src\js,视图如下所示:

 这是mxGraph的核心文件。

二、mxgraph核心文件介绍:

这个js库包含8大块mxClient这个js包含并动态导入了所有文件。 当前版本信息存储在mxClient.VERSION
  editor编辑器包提供实现图编辑器所需的类。这个包中的主要类是mxEditor
  view视图model模型包实现了由mxGraph表示的图形组件。它是一个mxGraphModel,包含mxcell,以及mxGraphView中缓存单元格的状态。根据mxStylesheet.样式表中定义的外观,使用mxcell渲染器来绘制单元格。撤销历史在mxUndoManager中实现。要在图上显示一个图标,可以使用mxCellOverlay。验证规则使用 mxMultiplicity进行定义。
  handler处理程序layout 布局shape 形状包分别包含事件监听器、布局算法和形状。图形事件监听器包括mxRubberband进行框线选择、mxTooltipHandler用于工具提示和mxGraphHandle用于基本单元格修改。mxCompactTreeLayout 实现了树布局算法,而shape 形状包提供了各种形状,它们是mxShape的子类。
  util包提供了实用程序类,包括用于复制粘贴mxClipboard、mxDatatransfer用于拖放的操作mxConstants 用于键的和样式表的值、mxEventmxUtils用于跨浏览器事件处理和通用功能、用于国际化的mxResources控制台输出的mxLog
  io包实现了一个通用的mxObjectCodec,用于将JavaScript对象转换为XML。最主要的类是mxCodec。mxCodecRegistry是定制codecs的全局注册表。

三、Mxgraph使用

1. 新建画板,画板相关操作

var container = document.getElementById("main");
        //设置背景样式
        container.style.background = 'url(editors/images/grid.gif)';        
       container.style.height = "300px";
        container.style.padding = "20px";
        //创建一个画板
        var graph = new mxGraph(container);
         //获取顶层,可以认为是父节点
        var parent = graph.getDefaultParent();

createVertex = function(){
            var container = document.getElementById("main");
            var graph = new mxGraph(container);
            var parent = graph.getDefaultParent();

            // 开启拖拽选择
            new mxRubberband(graph);    

            v1 = graph.insertVertex(parent, null, "text1", 100, 200, 100, 100);
            graph.insertVertex(parent, null, "text2", 250, 200, 100, 100);
            graph.insertVertex(parent, null, "text3", 400, 200, 100, 100);return graph;
        };

2 .style的使用,插入背景图

// 声明一个object
        var style = {};
        // 克隆一个object
        style = mxUtils.clone(style);
        style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_LABEL;  // 不设置这个属性 背景图片不出来
        // 边框颜色
        style[mxConstants.STYLE_STROKECOLOR] = '#999999';
        // 边框大小
        style[mxConstants.STYLE_STROKEWIDTH] = 10;
        // 字体颜色
        style[mxConstants.STYLE_FONTCOLOR] = '#FFFF00';
        // 文字水平方式
        style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
        // 文字垂直对齐
        style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_BOTTOM;
        // 字体大小
        style[mxConstants.STYLE_FONTSIZE] = 30;
        // 底图水平对齐
        style[mxConstants.STYLE_IMAGE_ALIGN] = mxConstants.ALIGN_CENTER;
        // 底图垂直对齐
        style[mxConstants.STYLE_IMAGE_VERTICAL_ALIGN] = mxConstants.ALIGN_CENTER;
        // 图片路径
        //style[mxConstants.STYLE_IMAGE] = 'images/icons48/gear.png';
        style[mxConstants.STYLE_IMAGE] = 'http://imgstatic.baidu.com/img/image/shouye/qizhi0822.jpg';
        // 背景图片宽 
        style[mxConstants.STYLE_IMAGE_WIDTH] = 150;
        // 背景图片高
        style[mxConstants.STYLE_IMAGE_HEIGHT] = 200;
        // 上间距设置
        // 即使下边定义了全局设置,但这里单独设置上边间距仍单独有效
        style[mxConstants.STYLE_SPACING_TOP] = 30;
        // 四边间距设置
        style[mxConstants.STYLE_SPACING] = 10;
        // 把定义好的样式object push到stylesheet
        graph.getStylesheet().putCellStyle("style1", style);
        //样式使用
       var v1 = graph.insertVertex(parent, null, "text1", 50, 50, 200, 200, "style1");

3、一些常用的方法

3.1  insertVertex 绘制图形

 //mxGraph.prototype.insertVertex = function(parent,id,value,x,y,width,height,style,relative)
        //parent画板父层,value值,x,y为坐标起点,width宽,height高
        //style样式  stylename;image=imageUrl
        //relative相对位置
        graph.insertVertex(parent, null, '第一个盒子', 50, 50, 80, 30,"style1");

3.2 insertEdge 连线

 //mxGraph.prototype.insertEdge = function(parent,id,value,source,target,style)
        //parent画板父层,value连线值,source起点,target重点,style样式
        graph.insertEdge(parent, null, 'box1 connect to box2', v1, v2 , "");

3.3 addCellOverlay 添加告警

// 开启提示
        graph.setTooltips(true);

        // 移出报警
        var delOverlay = function(id){
            // 获取ID单元
            var cell = graph.getModel().getCell(id);
            // 修改有报警物体的样式
            graph.setCellStyles(mxConstants.STYLE_FILLCOLOR, "#CCCCCC", [cell]);
            graph.setCellStyles(mxConstants.STYLE_FONTCOLOR, "#000000", [cell]);
            // 移除告警
            graph.removeCellOverlays(cell);
        };

        // 给物体添加报警
        var addOverlay = function(id, state){
            // 获取ID单元
            var cell = graph.getModel().getCell(id);
            // 修改有报警物体的样式
            graph.setCellStyles(mxConstants.STYLE_FILLCOLOR, "#FF0000", [cell]);
            graph.setCellStyles(mxConstants.STYLE_FONTCOLOR, "#FFFFFF", [cell]);
            // 添加告警
            graph.addCellOverlay(cell, createOverlay(graph.warningImage, '状态: '+state));
        };

        // 创建告警信息
        var createOverlay = function(image, tooltip){
            //function mxCellOverlay(image,tooltip,align,verticalAlign,offset,cursor)
            //image图片,tooltip提示,align位置,verticalAlign竖直位置
            var overlay = new mxCellOverlay(image, tooltip);
            overlay.addListener(mxEvent.CLICK, function(sender, evt){
                mxUtils.alert(tooltip);
            });            
            return overlay;
        };

3.4 添加按钮

// 添加按钮
        document.body.appendChild(mxUtils.button('修改背景颜色', function(evt){
            // Alaer
            mxUtils.alert("Oh! You will Click me!!");
            // 获取单元    
            var cell = graph.getModel().getCell(v1.id);
            // 修改样式
            graph.setCellStyles(mxConstants.STYLE_FILLCOLOR, "#000000", [cell]);
            graph.setCellStyles(mxConstants.STYLE_FONTCOLOR, "#FFFFFF", [cell]);
        }));

        // 添加按钮
        document.body.appendChild(mxUtils.button('还原背景颜色', function(evt){
            // 获取单元    
            var cell = graph.getModel().getCell(v1.id);
            // 获取默认样式
            var style = graph.getStylesheet().getDefaultVertexStyle();
            // 还原默认样式
            for(var i in mxConstants){
                graph.setCellStyles(mxConstants[i], style[mxConstants[i]], [cell]);
            }
        }));

3.5 缩放操作

// 居中缩放
        graph.centerZoom = true;
        // 放大按钮
        document.body.appendChild(mxUtils.button('放大 +', function(evt){
            graph.zoomIn();    
        }));
        // 缩小按钮
        document.body.appendChild(mxUtils.button('缩小 -', function(evt){
            graph.zoomOut();    
        }));
        // 还原按钮
        document.body.appendChild(mxUtils.button('还原 #', function(evt){
            graph.zoomActual();
            graph.zoomFactor = 1.2;
            input.value = 1.2;
        }));
        var input = document.createElement("input");
        input.type = "text";
        input.value = graph.zoomFactor;
        input.addEventListener("blur", function(){
            graph.zoomFactor = parseFloat(this.value, 10);                
        });
        document.body.appendChild(input);

3.6 拖拽连线操作

// 开启可以拖拽建立关系
        graph.setConnectable(true);
        // 开启方块上的文字编辑功能
        graph.setCellsEditable(false);
        // 启用对齐线帮助定位
        mxGraphHandler.prototype.guidesEnabled = true;
        // 选择基本元素开启
        graph.setEnabled(true);

3.7 图形形状介绍

var container = document.getElementById("main");
        container.style.background = 'url(editors/images/grid.gif)';
        container.style.width = "100%";
        container.style.height =  (window.screen.availHeight - 90 ) + "px";
        container.style.overflow = "hidden";
        var graph = new mxGraph(container);
        var parent = graph.getDefaultParent();

        // 画方块 默认情况下
        graph.insertVertex(parent, null, '矩形', 50, 50, 150, 150);
        // 画方块 圆角矩形
        // shape=rounded 定义圆角  arcSize=10 定义圆角弧度
        graph.insertVertex(parent, null, '圆角矩形', 300, 50, 150, 150, "rounded=true;perimeter=ellipsePerimeter;arcSize=20;");
        // 画椭圆
        // shape=elipse 定义椭圆  perimeter=ellipsePerimeter 让连线的箭头或起点触到边缘
        graph.insertVertex(parent, null, '椭圆', 550, 50, 150, 150, "shape=ellipse;perimeter=ellipsePerimeter;");
        // 画三角形
        // shape=triangl 定义三角形  perimeter=ellipsePerimeter 让连线的箭头或起点触到边缘 direction=south 让三角形倒立
        graph.insertVertex(parent, null, '三角形', 800, 50, 150, 150, "shape=triangle;perimeter=ellipsePerimeter;direction=south;");
        // 画菱形
        // shape=rhombus 定义菱形
        graph.insertVertex(parent, null, '三角形', 1050, 50, 150, 150, "shape=rhombus;perimeter=ellipsePerimeter;");
        // 画柱形
        // shape=cylinder 定义柱形
        graph.insertVertex(parent, null, '柱形', 1300, 50, 150, 150, "shape=cylinder;perimeter=ellipsePerimeter;");
        // 画人
        // shape=actor 定义演员
        graph.insertVertex(parent, null, '演员', 50, 300, 150, 150, "shape=actor;perimeter=ellipsePerimeter;");
        // 画云
        graph.insertVertex(parent, null, '云', 300, 300, 150, 150, "shape=cloud;perimeter=ellipsePerimeter;");
     //矩形默认情况下
        graph.insertVertex(parent, null, '矩形', 550, 300, 150, 150, "shape=rectangle;perimeter=ellipsePerimeter;");
     //泳道
        graph.insertVertex(parent, null, '泳道', 800, 300, 150, 150, "shape=swimlane;perimeter=ellipsePerimeter;");
      //双圆
        graph.insertVertex(parent, null, '双圆', 1050, 300, 150, 150, "shape=doubleEllipse;perimeter=ellipsePerimeter;");
     //六边形
        graph.insertVertex(parent, null, '六边形', 1300, 300, 150, 150, "shape=hexagon;perimeter=ellipsePerimeter;");

3.8 查看图形的xml

document.body.appendChild(mxUtils.button('View XML', function()
          {
             var encoder = new mxCodec();
             var node = encoder.encode(graph.getModel());
             mxUtils.popup(mxUtils.getPrettyXml(node), true);   //以窗口的方式展示处理
          }));

3.9 工具栏常用操作

buttons = [
            {
                label : "选择所有",
                fun : function(graph){
                    return function(evt){    
                        graph.selectAll();    
                    };
                }
            },
            {
                label : "选择一个",
                fun : function(graph){
                    return function(evt){    
                        graph.selectCell();    
                    };
                }
            },
            {
                label : "取消选择",    
                fun : function(graph){
                    return function(evt){
                        var cells = graph.getSelectionCells();    
                        graph.removeSelectionCells(cells);                            
                    };
                }
            },
            {
                label : "随机添加",    
                fun : function(graph){
                    return function(evt){
                        var randColor = function(){
                            return "rgb("+randint(0,255)+","+randint(0,255)+","+randint(0,255)+")";    
                        };
                        
                        var style = "fillColor=" + randColor() + "; fontColor=" + randColor();
                        var width = randint(50, 300);
                        var height = randint(50, 300);
                        var x = randint(0, 1200 - width);
                        var y = randint(0, 600 - height);

                        graph.insertVertex(graph.getDefaultParent(), null, "随机添加", x, y, width, height, style);
                    };    
                }
            },
            {
                label : "分组所选",
                fun : function(graph){
                    return function(evt){
                        var cells = graph.getSelectionCells();
                        graph.groupCells(null, 1, cells);
                    };
                }
            },
            {
                label : "取消分组",
                fun : function(graph){
                    return function(evt){
                        var cells = graph.getSelectionCells();
                        graph.ungroupCells(cells);
                    };
                }
            },
            {
                label : "删除所选",
                fun : function(graph){
                    return function(evt){
                        var cells = graph.getSelectionCells();
                        graph.removeCells(cells);
                    };
                }
            },
            {
                label : "缩小",
                fun : function(graph){
                    return function(evt){
                        graph.zoomOut();
                    };
                }
            },
            {
                label : "放大",
                fun : function(graph){
                    return function(evt){
                        graph.zoomIn();
                    };
                }
            },
            {
                label : "还原",
                fun : function(graph){
                    return function(evt){
                        graph.zoomActual();
                    };
                }
            },
            {
                label : "随机所选元素的位置",
                fun : function(graph){
                    return function(evt){
                        var cells = graph.getSelectionCells();
                        for(var i=0; i<cells.length; i++){
                            var x = randint(0, 1200 - cells[i].geometry.width);        
                            var y = randint(0, 600 - cells[i].geometry.height);        
                        }
                        graph.moveCells([cells[i]], x , y);                        
                    };
                }
            }

        ];

3.10 将图形的xml进行回显

var xml=
'<mxGraphModel>                                                                                             '+           
'  <root>                                                                                                                                          '+
'    <mxCell id="0"/>                                                                                                                              '+
'    <mxCell id="1" parent="0"/>                                                                                                                   '+
'    <app appId="" appName="" protocol="" ip="" port="" context="" heartBeatUrl="" id="2">                                                         '+
'      <mxCell style="verticalLabelPosition=top;verticalAlign=bottom;shadow=1;fillColor=#FFFFFF" vertex="1" connectable="0" parent="1" type="app"> '+
'        <mxGeometry x="100" y="320" width="20" height="40" as="geometry"/>                                                                        '+
'      </mxCell>                                                                                                                                   '+
'    </app>                                                                                                                                        '+
'  </root>                                                                                                                                         '+
'</mxGraphModel>                                                                                                                                   ';
var doc = mxUtils.parseXml(xml);
var codec = new mxCodec(doc);
codec.decode(doc.documentElement, graph.getModel());

四、mxGraph--mxGraph常用功能代码

1、设置当鼠标移到流程图的节点上时,给个绿色边框标记,鼠标移开时标记消失:

new mxCellTracker(editor.graph, '#00FF00');

2、给指定流程图节点加上红色边框标记

 /**
  * 给指定节点加上标记
  * cellId -- 节点ID
  **/
 flagCurNode: function(cellId) {
  var self = this;
  var model = self.editor.graph.getModel();
  var curCell = model.getCell(cellId);
  model.beginUpdate();
  try {
   self.editor.graph.setCellStyles("strokeColor", "red", [curCell]);
   self.editor.graph.setCellStyles("strokeWidth", "2", [curCell]);
  } finally {
   model.endUpdate();
  }
 }

3、取当前选择的流程图节点的信息 

 var self = this,
   graph = self.editor.graph,
   cell = graph.getSelectionCell();
  if (cell == null) {
   JxHint.alert(jx.wfx.nopic); //'没有选择图形元素!'
   return;
  }

  var objId = cell.getId();  //元素ID
  var enc = new mxCodec();
  var node = enc.encode(cell); //解析为DOM对象时自定义属性才可以识别
  var nodetype = node.getAttribute('nodetype'); //取节点类型,如果是线则为空
  var source = node.getAttribute('source');  //取线的来源节点ID,如果是节点则值为空

4、加载xml格式描述的流程图设计文件显示到设计控件中

  var hdCall = function(xmlfile) {
   if (xmlfile == null || xmlfile.length == 0) { 
    xmlfile = "<?xml version='1.0' encoding='utf-8'?>";
    xmlfile += "<mxGraphModel><root><mxCell id='0'/><mxCell id='1' parent='0'/></root></mxGraphModel>";
   }
   
   var doc = mxUtils.parseXml(xmlfile);
   var dec = new mxCodec(doc);
   dec.decode(doc.documentElement, self.editor.graph.getModel());
  };

5、保存设计信息到xml文件中  

var self = this,
   enc = new mxCodec(),
   graph = self.editor.graph,
   nodeGraph = enc.encode(graph.getModel()),
   rootNode = nodeGraph.getElementsByTagName('root')[0],
   mxCells = rootNode.childNodes;

//校验节点设置的有效性

...

//保存到xml中

var xmlFile = mxUtils.getPrettyXml(nodeGraph);

五、mxGraph--设置节点鼠标事件

//创建显示流程图的画布
 createEdit: function() {
  var self = this;
  //创建流程图编辑器,先检查加载图形库
  JxUtil.loadJxGraph();
  self.editor = new mxCanvas('public/lib/graph/config/showeditor_nav.xml');
  var graph = self.editor.graph;
  //设置编辑器为只读
  //由于设置setEnabled为false,分组块不能收缩了,所以采用下面的组合
  graph.setCellsEditable(false);
  graph.setCellsSelectable(false);
  graph.setConnectable(false);
  graph.setCellsMovable(false);
  
  //设置导航图的任务节点的鼠标与移入移出效果
  var track = new mxCellTracker(graph);
  track.mouseMove = function(sender, me) {
   var cell = this.getCell(me);
   if (cell && self.isTask(cell)) {
    //设置鼠标为样式为手状
    me.getState().setCursor('pointer');
    if (this.cur_cell == null) {
     this.cur_cell = cell;
     //设置鼠标移入节点效果
     self.moveNode(cell, true);
    }
   } else {
    //设置鼠标移出节点效果
    self.moveNode(this.cur_cell, false);
    this.cur_cell = null;
   }
  };

//捕获任务节点的鼠标点击事件
  graph.addListener(mxEvent.CLICK, function(sender, evt) {
   var cell = evt.getProperty('cell');
   var nodeId = self.getTaskId(cell);
   if (nodeId.length > 0) {
    self.clickCell(self.graphId, nodeId);
   }
  });
 },

//private 检查是否为任务节点
 isTask: function(cell) {
  if (cell == null) return false;
  
  var enc = new mxCodec();
  var node = enc.encode(cell);
  var nodetype = node.getAttribute('nodetype');
  if (nodetype == 'task') {
   return true;
  }
  return false;
 },

/**
  * 给指定的节点设置背景色
  * cell -- 当前节点
  * isin -- true 表示鼠标在节点上,false 表示鼠标没在节点上
  **/
 moveNode: function(cell, isin) {
  //为空与灰色的节点都不处理鼠标事件
  if (cell == null) return;
  if (cell.is_disabled) return;
  
  var self = this;
  var model = self.editor.graph.getModel();
  model.beginUpdate();
  try {
   self.editor.graph.setCellStyles("strokeColor", isin?"#A1A1FF":"#C3D9FF", [cell]);
   self.editor.graph.setCellStyles("fillColor", isin?"#A1A1FF":"#C3D9FF", [cell]);
  } finally {
   model.endUpdate();
  }
 }

六、mxGraph--右键菜单

js画图开发库--mxgraph--[menustyle-右键菜单.html] 

html代码:

<!Doctype html>  
<html xmlns=http://www.w3.org/1999/xhtml>  
    <head>  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">  
    <title>右键菜单</title>  
  
    <style type="text/css">  
        body div.mxPopupMenu {  
            -webkit-box-shadow: 3px 3px 6px #C0C0C0;  
            -moz-box-shadow: 3px 3px 6px #C0C0C0;  
            box-shadow: 3px 3px 6px #C0C0C0;  
            background: white;  
            position: absolute;  
            border: 3px solid #e7e7e7;  
            padding: 3px;  
        }  
        body table.mxPopupMenu {  
            border-collapse: collapse;  
            margin: 0px;  
        }  
        body tr.mxPopupMenuItem {  
            color: black;  
            cursor: default;  
        }  
        body td.mxPopupMenuItem {  
            padding: 6px 60px 6px 30px;  
            font-family: Arial;  
            font-size: 10pt;  
        }  
        body td.mxPopupMenuIcon {  
            background-color: white;  
            padding: 0px;  
        }  
        body tr.mxPopupMenuItemHover {  
            background-color: #eeeeee;  
            color: black;  
        }  
        table.mxPopupMenu hr {  
            border-top: solid 1px #cccccc;  
        }  
        table.mxPopupMenu tr {  
            font-size: 4pt;  
        }  
    </style>  
  
    <!-- 如果本文件的包与src不是在同一个目录,就要将basepath设置到src目录下 ??这个可以不用??-->  
    <script type="text/javascript">  
        mxBasePath = '../src';  
    </script>  
  
    <!-- 引入支持库文件 -->  
    <script type="text/javascript" src="../src/js/mxClient.js"></script>  
    <!-- 示例代码 -->  
    <script type="text/javascript">  
        // 程序在此方法中启动   
        function main(container)  
        {  
            // 检查浏览器支持  
            if (!mxClient.isBrowserSupported())  
            {  
                mxUtils.error('Browser is not supported!', 200, false);  
            }  
            else  
            {  
                // 禁用浏览器自带右键菜单  
                mxEvent.disableContextMenu(document.body);  
                  
                // 去锯齿效果  
                mxRectangleShape.prototype.crisp = true;  
                  
                // 在容器中创建图形  
                var graph = new mxGraph(container);  
  
                // 创建下拉菜单  
                new mxRubberband(graph);  
                  
                // 创建默认窗体  
                var parent = graph.getDefaultParent();  
                                  
                // 启动更新事务  
                graph.getModel().beginUpdate();  
                try  
                {  
                    var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);  
                    var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);  
                    var e1 = graph.insertEdge(parent, null, '', v1, v2);  
                }  
                finally  
                {  
                    // 结束更新事务  
                    graph.getModel().endUpdate();  
                }  
                  
                // 设置自动扩大鼠标悬停  
                graph.panningHandler.autoExpand = true;  
  
                // 覆写右键单击事件  
                graph.panningHandler.factoryMethod = function(menu, cell, evt)  
                {  
                    menu.addItem('Item 1', null, function()  
                    {  
                        alert('Item 1');  
                    });  
                      
                    menu.addItem('Item 2', null, function()  
                    {  
                        alert('Item 2');  
                    });  
  
                    menu.addSeparator();  
                      
                    var submenu1 = menu.addItem('Submenu 1', null, null);  
                      
                    menu.addItem('Subitem 1', null, function()  
                    {  
                        alert('Subitem 1');  
                    }, submenu1);  
                    menu.addItem('Subitem 1', null, function()  
                    {  
                        alert('Subitem 2');  
                    }, submenu1);  
                };  
            }  
        };  
    </script>  
</head>  
  
<!-- 页面载入时启动程序 -->  
<body onload="main(document.getElementById('graphContainer'))">  
  
    <!-- 创建带网格壁纸和曲线的一个容器  -->  
    <div id="graphContainer"  
        style="overflow:hidden;width:321px;height:241px;background:url('editors/images/grid.gif');cursor:default;">  
    </div>  
</body>  
</html>  

七、mxGraph学习笔记之设定一些通用的全局设置

这个网址有很多资料,很详细的例子

http://www.iteye.com/blogs/tag/mxgraph?page=2

// 无效 
graph.setEnabled(false); 

// 连接 
graph.setConnectable(true); 

// 提示信息 
graph.setTooltips(true); 

// 右键移动容器坐标轴 
graph.setPanning(true); 

// 容器大小自适应 
graph.setResizeContainer(true); 

// 鼠标框选 
new mxRubberband(graph); 

// 动态改变样式 
graph.getView().updateStyle = true; 

// 重复连接 
graph.setMultigraph(false); 

// Label 将显示 Html 格式的 Value 
graph.setHtmlLabels(true); 

// 禁用浏览器默认的右键菜单栏 
mxEvent.disableContextMenu(container); 

// 允许移动 Vertex 的 Label 
graph.setVertexLabelsMovable(true); 

// 禁止改变元素大小 
graph.setCellsResizable(false); 

// 允许连线的目标和源是同一元素 
graph.setAllowLoops(true); 

八、设置节点在线上(即:线和元素重叠式,线被节点遮住)

Java代码  

graph.selectEdges();//选中所有的线  
graph.orderCells(true);//使线在所有元素的底下   
graph.clearSelection();//取消选中的元素  

设置画布背景图片

Java代码  

var img = new mxImage(imageSrc,1280 ,1024);  // w:1280   h:1024  
graph.setBackgroundImage(img);   
graph.view.validate();  

 自定义ToolTip

Java代码  

graph.setTooltips(true);  
graph.getTooltipForCell = function(cell){  
    return "下级设备1:"+cell.downDevice1       
               + "\n下级设备2: "+cell.downDevice2     
     + "\n下级设备3: "+cell.downDevice3  
     + "\n下级设备数: "+cell.downDeviceNum;  
}  

事件

Java代码  

//移动元素触发事件  
graph.addListener(mxEvent.CELLS_MOVED,function(sender, evt){  
    //alert("CELLS_MOVED");     
    var cell = evt.getProperty('cell');   
                      
    if(cell==null&&sender.graphHandler.cells!=null){  
        cell = sender.graphHandler.cells[0];//保证cell有值,否则移动时cell  
    }   
               
    if(cell != null && cell.vertex == 1) {//代表鼠标点击的是节点  
        //alert("移动节点"+cell.id);      
        cell.autoSaveNode = '1';//给cell节点增加一个自定义属性,标识处于可保存状态     
    }    
});  

更新指定节点图片,可配合ajax无刷新实现告警时自动闪烁

Java代码  

graph.getModel().beginUpdate();  
try{  
    for (var i = 0; i < nodelist.length; i++) {  
                      
        //alert(nodelist[i].deviceid+1);  
        var cellId = nodelist[i].deviceid+1;  
        var picUrl = "";  
        //alert(cellId);   
        if(nodelist[i].sr_alarmsum>0)  picUrl = "red.gif";    
        else if (nodelist[i].sw_alarmsum >0)  picUrl = "orange.gif";                   
        var cell = graph.getModel().getCell(cellId);   
        // Updates the cell color and adds some tooltip information  
        if (cell != null) {     
            graph.setCellStyles(mxConstants.STYLE_IMAGE, "image;image="+picUrl, [cell]);   
        }    
    }  
                  
} finally {  
    graph.getModel().endUpdate();  
    //alert("ol1");   
}   

设置画布只能预览,禁止拖动或点击

Java代码  

graph.setEnabled(false);//graph只能预览  
graph.getCursorForCell = function(cell){//预览时鼠标悬浮到节点时,改变鼠标样式  
    if (cell != null && cell.value != null && cell.vertex ==1 )  
    {  
           return 'pointer';  
    }  
};  

九、mxGraph实现拓扑图拖动。mxGraph提交xml数据,java后台解析

需求:采用mxgraph实现可 拖动 拓扑图,并将移动后的拓扑图数据保存入数据库,供下次显示时读取

前台提交数据

Java代码  

//获取mxgraph拓扑图数据  
var enc1 = new mxCodec(mxUtils.createXmlDocument());  
var node1 = enc1.encode(graph.getModel());  
var xml1 = mxUtils.getXml(node1);  
          
//采用dwr的ajax方式向后台提交数据             
TopoService.saveTopoData(xml1,function(result){         //保存结果  
});  

后台解析数据

主要采用dom4j进行xml解析,分两套方案

Java代码  

/** 
     * 保存拓扑节点坐标信息 
     * @param userInfo 
     * @return 
     */  
    public int saveTopoData(String xmldata) {   
        int updateResult = 1;  
        Map<String, String> paraMap = new HashMap<String, String>();  
        InputSource in = new InputSource(new StringReader(xmldata));     
        //in.setEncoding("UTF-8");     
        in.setEncoding("GBK");   
        SAXReader reader = new SAXReader();     
        Document document;  
        try {  
            document = reader.read(in);  
            //获取所有拥有autoSaveNode属性的mxCell节点  
            System.out.println("===============所有需要保存的节点============");  
            System.out.println("======================方案二========================");  
            //---------------------------方案一-----------------------------------------------------  
            Element rootElt = document.getRootElement(); // 获取根节点  
            Element rootjd = rootElt.element("root");     
            Iterator rootiter = rootjd.elementIterator("mxCell"); // 获取根节点下的子节点mxCell  
            while (rootiter.hasNext()) {                   
                Element recordEle = (Element) rootiter.next();  
                String autoSaveNode = recordEle.attributeValue("autoSaveNode");  
                if(autoSaveNode!=null && !"".equals(autoSaveNode)){  
                    System.out.println("==节点允许保存:"+autoSaveNode);  
                    Element xyEle = recordEle.element("mxGeometry");  
                    System.out.println("节点id:"+recordEle.attributeValue("id"));  
                    System.out.println("x坐标:"+xyEle.attributeValue("x"));  
                    System.out.println("y坐标:"+xyEle.attributeValue("y"));  
                      
                    String zbElementX = xyEle.attributeValue("x")==null?"0":xyEle.attributeValue("x");  
                    String zbElementY = xyEle.attributeValue("y")==null?"0":xyEle.attributeValue("y");  
                    if (zbElementX.contains(".")) {  
                        zbElementX = zbElementX.substring(0,zbElementX.indexOf("."));  
                    }  
                      
                    if (zbElementY.contains(".")) {  
                        zbElementY = zbElementY.substring(0,zbElementY.indexOf("."));  
                    }  
                        
                     //节点只是移动了位置   
                    paraMap.put("deviceid",Long.parseLong(recordEle.attributeValue("deviceid"))+"");   
                    paraMap.put("xpoint",zbElementX);   
                    paraMap.put("ypoint",zbElementY);   
                      
                    topoDAO.saveTopoData(paraMap);  
                }   
            }  
            //-------------------------------------------------------------------------------------  
            //---------------------------方案二-----------------------------------------------------  
            /**String xpath = "//mxCell[@autoSaveNode]"; 
            List<Element> eList = document.selectNodes(xpath);//获取所有拥有autoSaveNode属性的mxCell节点 
             
            for (Iterator iterator = eList.iterator(); iterator.hasNext();) { 
                Element element =  (Element) iterator.next();   
                Element zbElement =    (Element) element.elements().get(0);//坐标数据节点   
                System.out.println("节点id:"+element.attributeValue("id")); 
                System.out.println("x坐标:"+zbElement.attributeValue("x")); 
                System.out.println("y坐标:"+zbElement.attributeValue("y")); 
                String zbElementX = zbElement.attributeValue("x")==null?"0":zbElement.attributeValue("x"); 
                String zbElementY = zbElement.attributeValue("y")==null?"0":zbElement.attributeValue("y"); 
                if (zbElementX.contains(".")) { 
                    zbElementX = zbElementX.substring(0,zbElementX.indexOf(".")); 
                } 
                 
                if (zbElementY.contains(".")) { 
                    zbElementY = zbElementY.substring(0,zbElementY.indexOf(".")); 
                } 
                   
                 //节点只是移动了位置  
                paraMap.put("deviceid",Long.parseLong(element.attributeValue("deviceid"))+"");  
                paraMap.put("xpoint",zbElementX);  
                paraMap.put("ypoint",zbElementY);  
                 
                topoDAO.saveTopoData(paraMap); 
                 
            }*/  
              
        } catch (Exception e) {  
            e.printStackTrace();  
              
        } finally {   
            return updateResult;  
              
        }  

最后为了方便大家的沟通与交流请加QQ群: 625787746

请进QQ群交流:【IT博客技术分享群①】:https://jq.qq.com/?_wv=1027&k=DceI0140

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT博客技术分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值