2 Star 4 Fork 3

Elmo Cho / mxGraph-demo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
index_with_ports.html 16.98 KB
一键复制 编辑 原始数据 按行查看 历史
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="./static/jquery-easyui-1.8.1/themes/gray/easyui.css">
<link rel="stylesheet" type="text/css" href="./static/jquery-easyui-1.8.1/themes/icon.css">
<script type="text/javascript" src="./static/jquery-easyui-1.8.1/jquery.min.js"></script>
<script type="text/javascript" src="./static/jquery-easyui-1.8.1/jquery.easyui.min.js"></script>
<link rel="stylesheet" href="./static/zTree_v3.5.40/css/zTreeStyle/zTreeStyle.css" type="text/css">
<link rel="stylesheet" href="./static/images/ztreeIconSkin.css" />
<script type="text/javascript" src="./static/zTree_v3.5.40/js/jquery.ztree.all.js"></script>
<script type="text/javascript" src="./static/js/jquery.cookie.js"></script>
<script type="text/javascript" src="./static/js/ztreeData.js"></script>
<script type="text/javascript" src="./static/js/jquery.xml2json.js"></script>
<script>
mxBasePath = './static/mxGraph';
</script>
<script type="text/javascript" src="./static/mxGraph/mxClient.js"></script>
<!-- Example code -->
<script type="text/javascript">
// Program starts here. Creates a sample graph in the
// DOM node with the specified ID. This function is invoked
// from the onLoad event handler of the document (see below).
var graph;
var parent;
function main(container) {
// Checks if the browser is supported
if (!mxClient.isBrowserSupported()) {
mxUtils.error('Browser is not supported!', 200, false);
} else {
// Creates the graph inside the given container
graph = new mxGraph(container);
// 开启拖拽选择
new mxRubberband(graph);
//流程图自动布局
//new mxCompactTreeLayout(graph);
// Gets the default parent for inserting new cells. This
// is normally the first child of the root (ie. layer 0).
parent = graph.getDefaultParent();
var currentPermission = null;
var apply = function(permission) {
graph.clearSelection();
permission.apply(graph);
graph.setEnabled(true);
// Updates the icons on the shapes - rarely
// needed and very slow for large graphs
graph.refresh();
currentPermission = permission;
};
//locked, createEdges, editEdges, editVertices, cloneCells
apply(new Permission(false, false, false, true, false));
// Extends hook functions to use permission object. This could
// be done by assigning the respective switches (eg.
// setMovable), but this approach is more flexible, doesn't
// override any existing behaviour or settings, and allows for
// dynamic conditions to be used in the functions. See the
// specification for more functions to extend (eg.
// isSelectable).
var oldDisconnectable = graph.isCellDisconnectable;
graph.isCellDisconnectable = function(cell, terminal, source) {
return oldDisconnectable.apply(this, arguments) &&
currentPermission.editEdges;
};
var oldTerminalPointMovable = graph.isTerminalPointMovable;
graph.isTerminalPointMovable = function(cell) {
return oldTerminalPointMovable.apply(this, arguments) &&
currentPermission.editEdges;
};
var oldBendable = graph.isCellBendable;
graph.isCellBendable = function(cell) {
return oldBendable.apply(this, arguments) &&
currentPermission.editEdges;
};
var oldLabelMovable = graph.isLabelMovable;
graph.isLabelMovable = function(cell) {
return oldLabelMovable.apply(this, arguments) &&
currentPermission.editEdges;
};
var oldMovable = graph.isCellMovable;
graph.isCellMovable = function(cell) {
return oldMovable.apply(this, arguments) &&
currentPermission.editVertices;
};
var oldResizable = graph.isCellResizable;
graph.isCellResizable = function(cell) {
return oldResizable.apply(this, arguments) &&
currentPermission.editVertices;
};
var oldEditable = graph.isCellEditable;
graph.isCellEditable = function(cell) {
return oldEditable.apply(this, arguments) &&
(this.getModel().isVertex(cell) &&
currentPermission.editVertices) ||
(this.getModel().isEdge(cell) &&
currentPermission.editEdges);
};
var oldDeletable = graph.isCellDeletable;
graph.isCellDeletable = function(cell) {
return oldDeletable.apply(this, arguments) &&
(this.getModel().isVertex(cell) &&
currentPermission.editVertices) ||
(this.getModel().isEdge(cell) &&
currentPermission.editEdges);
};
var oldCloneable = graph.isCellCloneable;
graph.isCellCloneable = function(cell) {
return oldCloneable.apply(this, arguments) &&
currentPermission.cloneCells;
};
}
};
function Permission(locked, createEdges, editEdges, editVertices, cloneCells) {
this.locked = (locked != null) ? locked : false;
this.createEdges = (createEdges != null) ? createEdges : true;
this.editEdges = (editEdges != null) ? editEdges : true;;
this.editVertices = (editVertices != null) ? editVertices : true;;
this.cloneCells = (cloneCells != null) ? cloneCells : true;;
};
Permission.prototype.apply = function(graph) {
graph.setConnectable(this.createEdges);
graph.setCellsLocked(this.locked);
}
$(function() {
main(document.getElementById('graphContainer'));
setTimeout(initXmlData, 100);
// initXmlData();
})
function initXmlData() {
var xmlData = $.cookie('mxGraph-xml-withPorts');
var node = mxUtils.parseXml(xmlData);
/**
* 脑仁疼,使用这种加载方式后居然不能再操作文档了
* 更新啥的也没有任何异常提示
*/
// decoder = new mxCodec(node.ownerDocument);
// decoder.decode(node, graph.getModel());
var json_obj = $.xml2json(node);
var mxCells = json_obj.root.mxCell;
if (mxCells.length > 2) {
graph.getModel().beginUpdate();
try {
for (var i = 2; i < mxCells.length; i++) {
var isLine = mxCells[i]["@edge"];
if (!isLine) {
var id = mxCells[i]["@id"];
var value = mxCells[i]["@value"];
var posX = mxCells[i].mxGeometry["@x"];
var posY = mxCells[i].mxGeometry["@y"];
var width = mxCells[i].mxGeometry["@width"];
var height = mxCells[i].mxGeometry["@height"];
var styleCls = mxCells[i]["@style"];
if(styleCls){
var style = [];
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_STROKECOLOR] = 'gray';
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_FILLCOLOR] = '#EEEEEE';
style[mxConstants.STYLE_GRADIENTCOLOR] = 'white';
style[mxConstants.STYLE_FONTCOLOR] = '#774400';
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_FONTSIZE] = '12';
style[mxConstants.STYLE_FONTSTYLE] = 1;
graph.getStylesheet().putCellStyle('exchanger', style);
var cell = graph.insertVertex(parent, id, value, posX, posY, width, height);
cell.setStyle(styleCls);
}else{
var cell = graph.insertVertex(parent, id, value, posX, posY, width, height);
}
}
}
for (var i = 2; i < mxCells.length; i++) {
var isLine = mxCells[i]["@edge"];
var id = mxCells[i]["@id"];
var value = mxCells[i]["@value"];
if (isLine && isLine == "1") {
//说明是线
var source = mxCells[i]["@source"];
var target = mxCells[i]["@target"];
var sourceCell = graph.getModel().getCell(source);
var targetCell = graph.getModel().getCell(target);
var line = graph.insertEdge(parent, id, value, sourceCell, targetCell, "");
//纠正数据,如果没有起始或终止的话,那就把它干掉
if (line.source == null || line.target == null) {
line.removeFromParent();
graph.refresh(line);
}
}
}
} finally {
// Updates the display
graph.getModel().endUpdate();
}
}
}
</script>
<SCRIPT type="text/javascript">
<!--
var setting = {
edit: {
enable: true,
showRemoveBtn: false,
showRenameBtn: false
},
data: {
simpleData: {
enable: true
}
},
callback: {
beforeDrag: beforeDrag,
beforeDrop: beforeDrop,
onDrop: initEquipmentToTheGraph,
onDblClick: initLineToTheGraph
}
};
function initLineToTheGraph(event, treeId, treeNode) {
//alert(treeNode ? treeNode.tId + ", " + treeNode.name : "isRoot");
graph.getModel().beginUpdate();
try {
if (treeNode.iconSkin == "line") {
var cells = graph.getSelectionCells();
if (cells.length != 2) {
$.messager.show({
title: '温馨提示',
msg: '请选择两个要连接的设备',
showType: 'slide'
});
} else {
var line = graph.insertEdge(parent, treeNode.id, treeNode.name, cells[0], cells[1], "");
//TODO 这里其实还需要在树里删除线缆,因为线缆不能重复用的.
}
}
} catch (e) {
} finally {
// Updates the display
graph.getModel().endUpdate();
}
};
function beforeDrag(treeId, treeNodes) {
for (var i = 0, l = treeNodes.length; i < l; i++) {
if (treeNodes[i].iconSkin == 'line') {
$.messager.show({
title: '温馨提示',
msg: '线缆请勿拖拽,选择起始及终止设备后双击线缆即可',
showType: 'slide'
});
return false;
}
}
return true;
}
function initEquipmentToTheGraph(event, treeId, treeNodes, targetNode, moveType) {
//将设备与线缆放置画布
graph.getModel().beginUpdate();
try {
for (var i = 0; i < treeNodes.length; i++) {
if (treeNodes[i].iconSkin == "server") {
var v1 = graph.insertVertex(parent, treeNodes[i].id, treeNodes[i].name, event.clientX - 200, event.clientY -
110,
100, 30);
} else if (treeNodes[i].iconSkin == "exchanger") {
var style = [];
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_STROKECOLOR] = 'gray';
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_FILLCOLOR] = '#EEEEEE';
style[mxConstants.STYLE_GRADIENTCOLOR] = 'white';
style[mxConstants.STYLE_FONTCOLOR] = '#774400';
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_FONTSIZE] = '12';
style[mxConstants.STYLE_FONTSTYLE] = 1;
graph.getStylesheet().putCellStyle('exchanger', style);
var cell = graph.insertVertex(parent, treeNodes[i].id, treeNodes[i].name, event.clientX - 200, event.clientY -
110,
110, 40);
cell.setStyle("exchanger");
} else if (treeNodes[i].iconSkin == "line") {
//不能创建没有起始终止点的线?
// var tempStart = graph.insertVertex(parent, null, "", event.clientX - 200, event.clientY - 110, 10, 10);
// var tempEnd = graph.insertVertex(parent, null, "", event.clientX - 100, event.clientY - 110, 10, 10);
// graph.insertEdge(parent,treeNodes[i].id, treeNodes[i].name,tempStart,tempEnd,"");
/**
* 不能曲线救国了,不管是隐藏还是移除对应线都没了
* 改为双击事件
*/
//tempStart.setVisible(false);
// tempStart.removeFromParent();
// tempEnd.removeFromParent();
// graph.refresh(cell);
}
}
} finally {
// Updates the display
graph.getModel().endUpdate();
}
};
function beforeDrop(treeId, treeNodes, targetNode, moveType) {
if (treeId) {
return false;
}
return targetNode ? targetNode.drop !== false : true;
}
$(document).ready(function() {
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
});
//-->
function saveGraph() {
var enc1 = new mxCodec(mxUtils.createXmlDocument());
var node1 = enc1.encode(graph.getModel());
var xml1 = mxUtils.getXml(node1);
$.cookie('mxGraph-xml-withPorts', xml1, {
expires: 7
});
// $.messager.show({
// title: '温馨提示',
// msg: '数据保存成功!',
// showType: 'slide'
// });
}
function saveGraphAndAlert() {
var enc1 = new mxCodec(mxUtils.createXmlDocument());
var node1 = enc1.encode(graph.getModel());
var xml1 = mxUtils.getXml(node1);
$.cookie('mxGraph-xml-withPorts', xml1, {
expires: 7
});
$.messager.show({
title: '温馨提示',
msg: '数据保存成功!',
showType: 'slide'
});
}
function exportGraph() {
var enc1 = new mxCodec(mxUtils.createXmlDocument());
var node1 = enc1.encode(graph.getModel());
var xml1 = mxUtils.getXml(node1);
$("#resultXML").html(xml1);
$('#w').window('open');
}
function clearAllAndRrfreshPage() {
$.messager.confirm('温馨提示', '您确定要清空重置网络拓扑图吗?', function(r) {
if (r) {
$.cookie('mxGraph-xml-withPorts', null);
location.reload();
}
});
}
function deleteCellOrLine() {
var cells = graph.getSelectionCells();
if (cells.length == 0) {
$.messager.alert('温馨提示', '请选择要删除的设备或线缆!', 'info');
} else if (cells.length > 1) {
$.messager.alert('温馨提示', '请选择一个进行删除操作!', 'info');
} else {
if (cells[0].edge) {
//说明是线缆
//如果啥都没有绑定的情况下可以删除
//执行删除操作并保存
graph.getModel().beginUpdate();
try {
cells[0].removeFromParent();
} finally {
graph.getModel().endUpdate();
}
saveGraph();
graph.refresh(cells[0]);
} else {
if (cells[0].edges && cells[0].edges.length > 0) {
$.messager.alert('温馨提示', '请先解绑线缆再删除!', 'info');
} else {
//执行删除操作并保存
graph.getModel().beginUpdate();
try {
cells[0].removeFromParent();
} finally {
graph.getModel().endUpdate();
}
saveGraph();
graph.refresh(cells[0]);
}
}
}
}
function zoomInGraph() {
graph.zoomIn();
}
function zoomOutGraph() {
graph.zoomOut();
}
function zoomActualGraph() {
graph.zoomActual();
}
</SCRIPT>
</head>
<body class="easyui-layout">
<div data-options="region:'north'" style="height:50px;background:#f1f1f1;">
<div style="font-size:18px;font-weight: bolder;padding:10px;">
mxGraph在线绘制网络拓扑结构图Demo2
<div style="float:right;">
<a target="_blank" class="easyui-linkbutton" href="https://gitee.com/caolj/mxGraph-demo">源代码</a>
</div>
</div>
</div>
<div data-options="region:'east',split:true" title="East" style="width:200px;"></div>
<div data-options="region:'west',split:true" title="配置区" style="width:200px;">
<ul id="treeDemo" class="ztree"></ul>
</div>
<div data-options="region:'center',title:'网络拓扑图'">
<div class="easyui-layout" data-options="fit:true,border:false">
<div data-options="region:'north',border:false" style="height:40px;padding:5px;background: #f1f1f1;overflow: hidden;border-bottom:1px solid #ddd;">
<a href="javascript:saveGraphAndAlert();" class="easyui-linkbutton" data-options="plain:true,iconCls:'icon-save'">保存</a>
<a href="javascript:deleteCellOrLine();" class="easyui-linkbutton" data-options="plain:true,iconCls:'icon-remove'">删除</a>
<a href="javascript:exportGraph();" class="easyui-linkbutton" data-options="plain:true,iconCls:'icon-print'">导出</a>
<a href="javascript:zoomInGraph();" class="easyui-linkbutton" data-options="plain:true,iconCls:'icon-zoom_in'">放大</a>
<a href="javascript:zoomOutGraph();" class="easyui-linkbutton" data-options="plain:true,iconCls:'icon-zoom_out'">缩小</a>
<a href="javascript:zoomActualGraph();" class="easyui-linkbutton" data-options="plain:true,iconCls:'icon-zoom'">实际大小</a>
<div style="float:right">
<a href="javascript:clearAllAndRrfreshPage();" class="easyui-linkbutton" data-options="plain:true,iconCls:'icon-clear'">一键清空</a>
</div>
</div>
<div data-options="region:'center',border:false">
<!-- Creates a container for the graph with a grid wallpaper -->
<div id="graphContainer" style="overflow:auto;width:100%;height:100%;background:url('./static/mxGraph/images/grid.gif')">
</div>
</div>
</div>
</div>
<div id="w" class="easyui-window" title="导出XML结果" data-options="modal:true,closed:true" style="width:600px;height:400px;overflow: hidden;">
<textarea id="resultXML" style="width:100%;height:100%;border:0px solid #fff;"></textarea>
</div>
</body>
</html>
JavaScript
1
https://gitee.com/Elmo-Cho/mxGraph-demo.git
git@gitee.com:Elmo-Cho/mxGraph-demo.git
Elmo-Cho
mxGraph-demo
mxGraph-demo
master

搜索帮助