入门指南:如何使用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 用于键的和样式表的值、mxEvent和mxUtils用于跨浏览器事件处理和通用功能、用于国际化的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
推荐阅读
-
使用Python和statsmodels进行多元线性回归与泊松回归的入门指南-1. 多元线性回归部分
-
超级详细指南:使用Maven搭建Spring MVC在Tomcat上进行本地部署并实现HelloWorld功能(第一部分)
-
教你如何为mxgraph图形添加默认布局 - Mxgraph使用指南第7部分
-
入门指南:如何使用Mxgraph.js(第一部分)
-
在Vue中集成mxGraph的入门指南(第一部分)
-
超简单!Jmeter安装与入门指南(第一部分)
-
入门指南:如何使用鲁班猫ZeroW卡片电脑烧录系统?
-
ANSYS Workbench入门指南,一步步教你如何使用
-
入门指南:如何在你的环境中使用ANSYS
-
入门 React 开发指南(第一部分)