想想好像好久没用写博客了! 由于最近想跳槽了(ps:尽管公司挽留,提出一些异与往常的挽留“制度”,But确实已经死心了) ,发现前一段时间一些做Hadoop,和Spark同事时常来请教网络拓扑图的有关问题,由于当时确实比较忙,没时间帮着一起分析,表示歉意!

先前整理过份简单的Demo 但是不详细  基于Web实现在线绘画拓扑图[GraphEditor]

首先呢这里是要详述的几个要点:(我用图是直接显示了~) (当然这套UI模块是后期改动的~重点不在这里)        [备案:后续使用文档]

显示拓扑图

其次呢是一些后期加上去的代码,我想既然用了网络拓扑图,后期的可塑性应该是很强的,部分都是后续需求加上去的!

言归正传,看完一些简单的流程图,我想都大概知道他的基本用途,和后期的塑造价值

一些简单的用途比如:做大数据Hadoop,Spark是的个个服务器之间的关系,以及关系流程图的描述; 大型企业的负载集群管理的关系以及流程图,安全管理,OA企业人士管理.....多事不可缺少的素材!

主要JQ代码模块:

上面的一些常量是一些属性!

用于绑定一些菜单信息

编辑保存

(主要文件:mxClient.js , Editor.js ,Graph.js,Shapes.js,EditorUi.js,Actions.js,Menus.js,Sidebar.js,                 Toolbar.js,Dialogs.js,jscolor.js )

核心文件代码如下:

EditorUi.js

 /**
*$id:Action 。JS,V 2015-3-23
*$author Dana丶Li$
*/
/**
* 构建了一种新的图形编辑器
* 编辑管理 实现方法管理
*/
EditorUi = function(editor, container)
{
this.editor = editor || new Editor();
this.container = container || document.body;
var graph = editor.graph;
//禁用滚动条
this.container.style.overflow = 'hidden'; var textEditing = mxUtils.bind(this, function(evt)
{
if (evt == null)
{
evt = window.event;
} if (this.isSelectionAllowed(evt))
{
return true;
} return graph.isEditing() || this.dialog != null;
}); //禁用文本选择而不是编辑没有对话框可见
if (this.container == document.body)
{
document.onselectstart = textEditing;
document.onmousedown = textEditing;
} //使用内置的上下文菜单编辑时
if (mxClient.IS_IE && document.documentMode != 9)
{
mxEvent.addListener(this.container, 'contextmenu', textEditing);
}
else
{
this.container.oncontextmenu = textEditing;
} //图像预fetches子菜单
new Image().src = mxPopupMenu.prototype.submenuImage; //预取连接图像
if (mxConnectionHandler.prototype.connectImage != null)
{
new Image().src = mxConnectionHandler.prototype.connectImage.src;
} //创建用户界面
this.actions = new Actions(this);
this.menus = new Menus(this);
this.createDivs();
this.refresh();
this.createUi(); //contains the given the inside main图审小组
graph.init(this.diagramContainer);
graph.refresh(); //使容器的滚动条和设置光标样式
graph.container.setAttribute('tabindex', '0');
graph.container.style.overflow = (touchStyle) ? 'hidden' : 'auto';
graph.container.style.cursor = 'default';
graph.container.style.backgroundImage = 'url(' + IMAGE_PATH + '/grid.gif)';
graph.container.focus(); //保持图形容器集中在鼠标按下
var graphFireMouseEvent = graph.fireMouseEvent;
graph.fireMouseEvent = function(evtName, me, sender)
{
if (evtName == mxEvent.MOUSE_DOWN)
{
this.container.focus();
} graphFireMouseEvent.apply(this, arguments);
}; //在鼠标经过时自动扩展配置
graph.panningHandler.autoExpand = true; //对上下文菜单
graph.panningHandler.factoryMethod = mxUtils.bind(this, function(menu, cell, evt)
{
this.menus.createPopupMenu(menu, cell, evt);
}); //初始化轮廓
editor.outline.init(this.outlineContainer); //隐藏菜单
var md = (mxClient.IS_TOUCH) ? 'touchstart' : 'mousedown';
mxEvent.addListener(document, md, mxUtils.bind(this, function(evt)
{
graph.panningHandler.hideMenu();
})); //增加了手势操作(缩放)
if (mxClient.IS_TOUCH)
{
mxEvent.addListener(graph.container, 'gesturechange',
mxUtils.bind(this, function(evt)
{
graph.view.getDrawPane().setAttribute('transform', 'scale(' + evt.scale + ')');
graph.view.getOverlayPane().style.visibility = 'hidden';
})
); mxEvent.addListener(graph.container, 'gestureend',
mxUtils.bind(this, function(evt)
{
graph.view.getDrawPane().removeAttribute('transform');
graph.zoomToCenter = true;
graph.zoom(evt.scale);
graph.view.getOverlayPane().style.visibility = 'visible';
})
);
} // Create handler for key events
var keyHandler = this.createKeyHandler(editor); // Getter for key handler
this.getKeyHandler = function()
{
return keyHandler;
}; // Shows dialog if changes are lost
window.onbeforeunload = function()
{
if (editor.modified)
{
//return mxResources.get('allChangesLost');
}
}; // Updates the editor UI after the window has been resized
mxEvent.addListener(window, 'resize', mxUtils.bind(this, function()
{
this.refresh();
graph.sizeDidChange();
this.editor.outline.update(false);
this.editor.outline.outline.sizeDidChange();
})); // Updates action and menu states
this.init();
this.open();
}; /**
* Specifies the size of the split bar.
*/
EditorUi.prototype.splitSize = (mxClient.IS_TOUCH) ? 16 : 8; /**
* Specifies the height of the menubar. Default is 34.
*/
EditorUi.prototype.menubarHeight = 34; /**
* Specifies the height of the toolbar. Default is 46.
*/
EditorUi.prototype.toolbarHeight = 46; /**
* Specifies the height of the footer. Default is 28.
*/
EditorUi.prototype.footerHeight = 28; /**
* Specifies the position of the horizontal split bar. Default is 190.
*/
EditorUi.prototype.hsplitPosition = 190; /**
* Specifies the position of the vertical split bar. Default is 190.
*/
EditorUi.prototype.vsplitPosition = 190; /**
* Installs the listeners to update the action states.
*/
EditorUi.prototype.init = function()
{
// Updates action states
this.addUndoListener();
this.addSelectionListener(); // Overrides clipboard to update paste action state
var paste = this.actions.get('paste'); var updatePaste = function()
{
paste.setEnabled(!mxClipboard.isEmpty());
}; var mxClipboardCut = mxClipboard.cut;
mxClipboard.cut = function()
{
mxClipboardCut.apply(this, arguments);
updatePaste();
}; var mxClipboardCopy = mxClipboard.copy;
mxClipboard.copy = function()
{
mxClipboardCopy.apply(this, arguments);
updatePaste();
};
}; /**
* Hook for allowing selection and context menu for certain events.
*/
EditorUi.prototype.isSelectionAllowed = function(evt)
{
return false;
}; /**
* Opens the current diagram via the window.opener if one exists.
*/
EditorUi.prototype.open = function()
{
// Cross-domain window access is not allowed in FF, so if we
// were opened from another domain then this will fail.
try
{
if (window.opener != null && window.opener.openFile != null)
{
window.opener.openFile.setConsumer(mxUtils.bind(this, function(xml, filename)
{
try
{
var doc = mxUtils.parseXml(xml);
this.editor.setGraphXml(doc.documentElement);
this.editor.modified = false;
this.editor.undoManager.clear(); if (filename != null)
{
this.editor.filename = filename;
}
}
catch (e)
{
mxUtils.alert(mxResources.get('invalidOrMissingFile') + ': ' + e.message);
}
}));
}
}
catch(e)
{
// ignore
}
}; /**
* 在给定的文件名保存当前图。
*/
EditorUi.prototype.save = function()
{
var xml = mxUtils.getXml(this.editor.getGraphXml());
//火狐浏览器
//if (navigator.userAgent.indexOf('Firefox') >= 0){
//}
xml="<mxGraphModel grid=\"0\" guides=\"1\" tooltips=\"1\" connect=\"1\" fold=\"1\" page=\"0\" pageScale=\"1\" pageWidth=\"826\" pageHeight=\"1169\">"+xml+"</mxGraphModel>" //将xml代码保存至服务器文件
$.post($("#path").val()+"/SaveToXmlServlet",{"tp":$("#mapTp").val(),"xml":xml,"type":"set"},function(text){
if(text=="0"){
alert("保存失败!");
}
});
}; /**
* 返回一个拷贝没有状态这个编辑器的URL。
*/
EditorUi.prototype.getUrl = function(pathname)
{
var href = (pathname != null) ? pathname : window.location.pathname;
var parms = (pathname.indexOf('?') > 0) ? 1 : 0; // Removes template URL parameter for new blank diagram
for (var key in urlParams)
{
if (parms == 0)
{
href += '?';
}
else
{
href += '&';
} href += key + '=' + urlParams[key];
parms++;
} return href;
}; /**
* 更新的撤销/重做项的状态。
*/
EditorUi.prototype.addUndoListener = function()
{
var undo = this.actions.get('undo');
var redo = this.actions.get('redo'); var undoMgr = this.editor.undoManager; var undoListener = function()
{
undo.setEnabled(undoMgr.canUndo());
redo.setEnabled(undoMgr.canRedo());
}; undoMgr.addListener(mxEvent.ADD, undoListener);
undoMgr.addListener(mxEvent.UNDO, undoListener);
undoMgr.addListener(mxEvent.REDO, undoListener);
undoMgr.addListener(mxEvent.CLEAR, undoListener); // Updates the button states once
undoListener();
}; /**
* Updates the states of the given toolbar items based on the selection.
*/
EditorUi.prototype.addSelectionListener = function()
{
var selectionListener = mxUtils.bind(this, function()
{
var graph = this.editor.graph;
var selected = !graph.isSelectionEmpty();
var vertexSelected = false;
var edgeSelected = false; var cells = graph.getSelectionCells(); if (cells != null)
{
for (var i = 0; i < cells.length; i++)
{
var cell = cells[i]; if (graph.getModel().isEdge(cell))
{
edgeSelected = true;
} if (graph.getModel().isVertex(cell))
{
vertexSelected = true;
} if (edgeSelected && vertexSelected)
{
break;
}
}
} // 更新动作状态
var actions = ['cut', 'copy', 'delete', 'duplicate', 'bold', 'italic', 'style', 'fillColor',
'gradientColor', 'underline', 'fontColor', 'strokeColor', 'backgroundColor',
'borderColor', 'toFront', 'toBack', 'dashed', 'rounded', 'shadow', 'rotate',
'autosize']; for (var i = 0; i < actions.length; i++)
{
this.actions.get(actions[i]).setEnabled(selected);
} this.actions.get('rotation').setEnabled(vertexSelected);
this.actions.get('group').setEnabled(graph.getSelectionCount() > 1);
this.actions.get('ungroup').setEnabled(graph.getSelectionCount() == 1 &&
graph.getModel().getChildCount(graph.getSelectionCell()) > 0);
var oneVertexSelected = vertexSelected && graph.getSelectionCount() == 1;
this.actions.get('removeFromGroup').setEnabled(oneVertexSelected &&
graph.getModel().isVertex(graph.getModel().getParent(graph.getSelectionCell()))); //更新菜单状态
var menus = ['fontFamily', 'fontSize', 'alignment', 'position', 'text', 'format',
'arrange', 'linewidth', 'spacing', 'gradient']; for (var i = 0; i < menus.length; i++)
{
this.menus.get(menus[i]).setEnabled(selected);
} menus = ['line', 'lineend', 'linestart']; for (var i = 0; i < menus.length; i++)
{
this.menus.get(menus[i]).setEnabled(edgeSelected);
} this.actions.get('setAsDefaultEdge').setEnabled(edgeSelected); this.menus.get('align').setEnabled(graph.getSelectionCount() > 1);
this.menus.get('direction').setEnabled(vertexSelected || (edgeSelected &&
graph.isLoop(graph.view.getState(graph.getSelectionCell()))));
this.menus.get('navigation').setEnabled(graph.foldingEnabled && ((graph.view.currentRoot != null) ||
(graph.getSelectionCount() == 1 && graph.isValidRoot(graph.getSelectionCell()))));
this.actions.get('home').setEnabled(graph.view.currentRoot != null);
this.actions.get('exitGroup').setEnabled(graph.view.currentRoot != null);
var groupEnabled = graph.getSelectionCount() == 1 && graph.isValidRoot(graph.getSelectionCell());
this.actions.get('enterGroup').setEnabled(groupEnabled);
this.actions.get('expand').setEnabled(groupEnabled);
this.actions.get('collapse').setEnabled(groupEnabled);
this.actions.get('editLink').setEnabled(graph.getSelectionCount() == 1);
this.actions.get('openLink').setEnabled(graph.getSelectionCount() == 1 &&
graph.getLinkForCell(graph.getSelectionCell()) != null);
}); this.editor.graph.getSelectionModel().addListener(mxEvent.CHANGE, selectionListener);
selectionListener();
}; /**
* Refreshes the viewport.
*/
EditorUi.prototype.refresh = function()
{
var quirks = mxClient.IS_IE && (document.documentMode == null || document.documentMode == 5);
var w = this.container.clientWidth;
var h = this.container.clientHeight; if (this.container == document.body)
{
w = document.body.clientWidth || document.documentElement.clientWidth;
h = (quirks) ? document.body.clientHeight || document.documentElement.clientHeight : document.documentElement.clientHeight;
} var effHsplitPosition = Math.max(0, Math.min(this.hsplitPosition, w - this.splitSize - 20));
var effVsplitPosition = Math.max(0, Math.min(this.vsplitPosition, h - this.menubarHeight - this.toolbarHeight - this.footerHeight - this.splitSize - 1)); this.menubarContainer.style.height = this.menubarHeight + 'px';
this.toolbarContainer.style.top = this.menubarHeight + 'px';
this.toolbarContainer.style.height = this.toolbarHeight + 'px';
this.sidebarContainer.style.top = (this.menubarHeight + this.toolbarHeight) + 'px';
this.sidebarContainer.style.width = effHsplitPosition + 'px';
this.outlineContainer.style.width = effHsplitPosition + 'px';
this.outlineContainer.style.height = effVsplitPosition + 'px';
this.outlineContainer.style.bottom = this.footerHeight + 'px';
this.diagramContainer.style.left = (effHsplitPosition + this.splitSize) + 'px';
this.diagramContainer.style.top = this.sidebarContainer.style.top;
this.footerContainer.style.height = this.footerHeight + 'px';
this.hsplit.style.top = this.sidebarContainer.style.top;
this.hsplit.style.bottom = this.outlineContainer.style.bottom;
this.hsplit.style.left = effHsplitPosition + 'px';
this.vsplit.style.width = this.sidebarContainer.style.width;
this.vsplit.style.bottom = (effVsplitPosition + this.footerHeight) + 'px'; if (quirks)
{
this.menubarContainer.style.width = w + 'px';
this.toolbarContainer.style.width = this.menubarContainer.style.width;
var sidebarHeight = (h - effVsplitPosition - this.splitSize - this.footerHeight - this.menubarHeight - this.toolbarHeight);
this.sidebarContainer.style.height = sidebarHeight + 'px';
this.diagramContainer.style.width = (w - effHsplitPosition - this.splitSize) + 'px';
var diagramHeight = (h - this.footerHeight - this.menubarHeight - this.toolbarHeight);
this.diagramContainer.style.height = diagramHeight + 'px';
this.footerContainer.style.width = this.menubarContainer.style.width;
this.hsplit.style.height = diagramHeight + 'px';
}
else
{
this.sidebarContainer.style.bottom = (effVsplitPosition + this.splitSize + this.footerHeight) + 'px';
this.diagramContainer.style.bottom = this.outlineContainer.style.bottom;
}
}; /**
* Creates the required containers.
*/
EditorUi.prototype.createDivs = function()
{
this.menubarContainer = this.createDiv('geMenubarContainer');
this.toolbarContainer = this.createDiv('geToolbarContainer');
this.sidebarContainer = this.createDiv('geSidebarContainer');
this.outlineContainer = this.createDiv('geOutlineContainer');
this.diagramContainer = this.createDiv('geDiagramContainer');
this.footerContainer = this.createDiv('geFooterContainer');
this.hsplit = this.createDiv('geHsplit');
this.vsplit = this.createDiv('geVsplit'); // Sets static style for containers
this.menubarContainer.style.top = '0px';
this.menubarContainer.style.left = '0px';
this.menubarContainer.style.right = '0px';
this.toolbarContainer.style.left = '0px';
this.toolbarContainer.style.right = '0px';
this.sidebarContainer.style.left = '0px';
this.outlineContainer.style.left = '0px';
this.diagramContainer.style.right = '0px';
this.footerContainer.style.left = '0px';
this.footerContainer.style.right = '0px';
this.footerContainer.style.bottom = '0px';
this.vsplit.style.left = '0px';
this.vsplit.style.height = this.splitSize + 'px';
this.hsplit.style.width = this.splitSize + 'px';
}; /**
* Creates the required containers.
*/
EditorUi.prototype.createUi = function()
{
// Creates menubar
this.menubar = this.menus.createMenubar(this.createDiv('geMenubar'));
this.menubarContainer.appendChild(this.menubar.container); // Creates toolbar
this.toolbar = this.createToolbar(this.createDiv('geToolbar'));
this.toolbarContainer.appendChild(this.toolbar.container); // Creates the sidebar
this.sidebar = this.createSidebar(this.sidebarContainer); // Creates the footer
this.footerContainer.appendChild(this.createFooter()); // Adds status bar in menubar
this.statusContainer = this.createStatusContainer(); // Connects the status bar to the editor status
this.editor.addListener('statusChanged', mxUtils.bind(this, function()
{
this.setStatusText(this.editor.getStatus());
})); this.setStatusText(this.editor.getStatus());
this.menubar.container.appendChild(this.statusContainer); // Inserts into DOM
this.container.appendChild(this.menubarContainer);
this.container.appendChild(this.toolbarContainer);
this.container.appendChild(this.sidebarContainer);
this.container.appendChild(this.outlineContainer);
this.container.appendChild(this.diagramContainer);
this.container.appendChild(this.footerContainer);
this.container.appendChild(this.hsplit);
this.container.appendChild(this.vsplit); // HSplit
this.addSplitHandler(this.hsplit, true, 0, mxUtils.bind(this, function(value)
{
this.hsplitPosition = value;
this.refresh();
this.editor.graph.sizeDidChange();
this.editor.outline.update(false);
this.editor.outline.outline.sizeDidChange();
})); // VSplit
this.addSplitHandler(this.vsplit, false, this.footerHeight, mxUtils.bind(this, function(value)
{
this.vsplitPosition = value;
this.refresh();
this.editor.outline.update(false);
this.editor.outline.outline.sizeDidChange();
}));
}; /**
* Creates a new toolbar for the given container.
*/
EditorUi.prototype.createStatusContainer = function()
{
var container = document.createElement('a');
container.className = 'geItem geStatus'; return container;
}; /**
* Creates a new toolbar for the given container.
*/
EditorUi.prototype.setStatusText = function(value)
{
this.statusContainer.innerHTML = value;
}; /**
* Creates a new toolbar for the given container.
*/
EditorUi.prototype.createToolbar = function(container)
{
return new Toolbar(this, container);
}; /**
* Creates a new sidebar for the given container.
*/
EditorUi.prototype.createSidebar = function(container)
{
return new Sidebar(this, container);
}; /**
* Creates and returns a new footer.
*/
EditorUi.prototype.createFooter = function()
{
return this.createDiv('geFooter');
}; /**
* Creates the actual toolbar for the toolbar container.
*/
EditorUi.prototype.createDiv = function(classname)
{
var elt = document.createElement('div');
elt.className = classname; return elt;
}; /**
* Updates the states of the given undo/redo items.
*/
EditorUi.prototype.addSplitHandler = function(elt, horizontal, dx, onChange)
{
var start = null;
var initial = null; function getValue()
{
return parseInt(((horizontal) ? elt.style.left : elt.style.bottom));
} var md = (mxClient.IS_TOUCH) ? 'touchstart' : 'mousedown';
var mm = (mxClient.IS_TOUCH) ? 'touchmove' : 'mousemove';
var mu = (mxClient.IS_TOUCH) ? 'touchend' : 'mouseup'; mxEvent.addListener(elt, md, function(evt)
{
start = new mxPoint(mxEvent.getClientX(evt), mxEvent.getClientY(evt));
initial = getValue();
mxEvent.consume(evt);
}); function moveHandler(evt)
{
if (start != null)
{
var pt = new mxPoint(mxEvent.getClientX(evt), mxEvent.getClientY(evt));
onChange(Math.max(0, initial + ((horizontal) ? (pt.x - start.x) : (start.y - pt.y)) - dx));
mxEvent.consume(evt);
}
} mxEvent.addListener(document, mm, moveHandler); mxEvent.addListener(document, mu, function(evt)
{
moveHandler(evt);
start = null;
initial = null;
});
}; /**
* Displays a print dialog.
*/
EditorUi.prototype.showDialog = function(elt, w, h, modal, closable, onClose)
{
this.hideDialog();
this.dialog = new Dialog(this, elt, w, (mxClient.IS_VML) ? h - 12 : h, modal, closable, onClose);
}; /**
* Displays a print dialog.
*/
EditorUi.prototype.hideDialog = function()
{
if (this.dialog != null)
{
this.dialog.close();
this.dialog = null;
this.editor.graph.container.focus();
}
}; /**
* Adds the label menu items to the given menu and parent.
*/
EditorUi.prototype.openFile = function()
{
// Closes dialog after open
window.openFile = new OpenFile(mxUtils.bind(this, function()
{
this.hideDialog();
})); // Removes openFile if dialog is closed
this.showDialog(new OpenDialog(this).container, 300, 180, true, true, function()
{
window.openFile = null;
});
}; /**
* Adds the label menu items to the given menu and parent.
*/
EditorUi.prototype.saveFile = function(forceDialog)
{
if (!forceDialog && this.editor.filename != null)
{
this.save(this.editor.getOrCreateFilename());
}
else
{
this.showDialog(new SaveDialog(this).container, 300, 100, true, true);
}
}; /**
* Executes the given layout.
*/
EditorUi.prototype.executeLayout = function(layout, animate, ignoreChildCount)
{
var graph = this.editor.graph;
var cell = graph.getSelectionCell(); graph.getModel().beginUpdate();
try
{
layout.execute(graph.getDefaultParent(), cell);
}
catch (e)
{
throw e;
}
finally
{
// Animates the changes in the graph model except
// for Camino, where animation is too slow
if (animate && navigator.userAgent.indexOf('Camino') < 0)
{
// New API for animating graph layout results asynchronously
var morph = new mxMorphing(graph);
morph.addListener(mxEvent.DONE, mxUtils.bind(this, function()
{
graph.getModel().endUpdate();
})); morph.startAnimation();
}
else
{
graph.getModel().endUpdate();
}
}
}; /**
* Creates the keyboard event handler for the current graph and history.
*/
EditorUi.prototype.createKeyHandler = function(editor)
{
var graph = this.editor.graph;
var keyHandler = new mxKeyHandler(graph); // Routes command-key to control-key on Mac
keyHandler.isControlDown = function(evt)
{
return mxEvent.isControlDown(evt) || (mxClient.IS_MAC && evt.metaKey);
}; // Helper function to move cells with the cursor keys
function nudge(keyCode)
{
if (!graph.isSelectionEmpty())
{
var dx = 0;
var dy = 0; if (keyCode == 37)
{
dx = -1;
}
else if (keyCode == 38)
{
dy = -1;
}
else if (keyCode == 39)
{
dx = 1;
}
else if (keyCode == 40)
{
dy = 1;
} graph.moveCells(graph.getSelectionCells(), dx, dy);
graph.scrollCellVisible(graph.getSelectionCell());
}
}; // Binds keystrokes to actions
var bindAction = mxUtils.bind(this, function(code, control, key, shift)
{
var action = this.actions.get(key); if (action != null)
{
var f = function()
{
if (action.enabled)
{
action.funct();
}
}; if (control)
{
if (shift)
{
keyHandler.bindControlShiftKey(code, f);
}
else
{
keyHandler.bindControlKey(code, f);
}
}
else
{
if (shift)
{
keyHandler.bindShiftKey(code, f);
}
else
{
keyHandler.bindKey(code, f);
}
}
}
}); var ui = this;
var keyHandleEscape = keyHandler.escape;
keyHandler.escape = function(evt)
{
ui.hideDialog();
keyHandleEscape.apply(this, arguments);
}; // Ignores enter keystroke. Remove this line if you want the
// enter keystroke to stop editing.
keyHandler.enter = function() {};
keyHandler.bindKey(8, function() { graph.foldCells(true); }); // Backspace
keyHandler.bindKey(13, function() { graph.foldCells(false); }); // Enter
keyHandler.bindKey(33, function() { graph.exitGroup(); }); // Page Up
keyHandler.bindKey(34, function() { graph.enterGroup(); }); // Page Down
keyHandler.bindKey(36, function() { graph.home(); }); // Home
keyHandler.bindKey(35, function() { graph.refresh(); }); // End
keyHandler.bindKey(37, function() { nudge(37); }); // Left arrow
keyHandler.bindKey(38, function() { nudge(38); }); // Up arrow
keyHandler.bindKey(39, function() { nudge(39); }); // Right arrow
keyHandler.bindKey(40, function() { nudge(40); }); // Down arrow
keyHandler.bindKey(113, function() { graph.startEditingAtCell(); });
bindAction(46, false, 'delete'); // Delete
bindAction(82, true, 'rotate'); // Ctrl+R
bindAction(83, true, 'save'); // Ctrl+S
bindAction(83, true, 'saveAs', true); // Ctrl+Shift+S
bindAction(107, false, 'zoomIn'); // Add
bindAction(109, false, 'zoomOut'); // Subtract
bindAction(65, true, 'selectAll'); // Ctrl+A
bindAction(86, true, 'selectVertices', true); // Ctrl+Shift+V
bindAction(69, true, 'selectEdges', true); // Ctrl+Shift+E
bindAction(69, true, 'export'); // Ctrl+Shift+E
bindAction(66, true, 'toBack'); // Ctrl+B
bindAction(70, true, 'toFront'); // Ctrl+F
bindAction(68, true, 'duplicate'); // Ctrl+D
bindAction(90, true, 'undo'); // Ctrl+Z
bindAction(89, true, 'redo'); // Ctrl+Y
bindAction(88, true, 'cut'); // Ctrl+X
bindAction(67, true, 'copy'); // Ctrl+C
bindAction(81, true, 'connect'); // Ctrl+Q
bindAction(86, true, 'paste'); // Ctrl+V
bindAction(71, true, 'group'); // Ctrl+G
bindAction(71, true, 'grid', true); // Ctrl+Shift+G
bindAction(85, true, 'ungroup'); // Ctrl+U
bindAction(112, false, 'about'); // F1 return keyHandler;
};

这里是图形化操作以后保存拓扑对于的Xml文件,便于再次访问,或者查看的时候加载原信息!

如操作功能:

对应的通过上面EditorUi.js文件中EditorUi.prototype.save = function()控制,我是通过一个Servlet来保存XML文件

 package com.visec.systemConfig;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* <p>Title: 网络拓扑图保存</p>
* <p>Description: 将网络拓扑图保存至对应的xml文件中 以及 读取网络拓扑图对应的xml文件</p>
* <p>Copyright: Copyright (c) 2015</p>
* <p>Company: XXX科技</p>
* @author 李尚志
* @version 3.0
*/
public class SaveToXmlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
String type = request.getParameter("type");
String tp = request.getParameter("tp");
StringBuffer result = new StringBuffer("");
String xmlPath=new String("");
String strPath = this.getClass().getResource("/").toString();
xmlPath = ("qsy".equals(tp))?"network_map/network_qsy.xml":("dzj".equals(tp))?"network_map/network_dzj.xml":("zdw".equals(tp))?"network_map/network_zdw.xml":"network_map/network_sp.xml";
String osName = System.getProperties().getProperty("os.name");
if(osName.toLowerCase().indexOf("windows")>-1){
strPath=strPath.substring(6)+xmlPath;
}else{
strPath=strPath.substring(5)+xmlPath;
}
File file = new File(strPath);
if(file.isFile()){//判断该路径是否为一个文件
if("set".equals(type.toLowerCase())){//文件保存
String xml = request.getParameter("xml");
if(xml==null||"".equals(xml)){
result.append("0");
}else{
RandomAccessFile randomAccessFile = new RandomAccessFile(strPath, "rw");
randomAccessFile.seek(0);
randomAccessFile.setLength(0);
randomAccessFile.write(xml.getBytes());
randomAccessFile.close();
result.append("1");
}
}else if("get".equals(type.toLowerCase())){//获取文件信息
//开始读取
BufferedReader reader = new BufferedReader(new FileReader(new File(strPath)));
String tempString = null;
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null){
result.append(tempString);
}
reader.close();
}
}else{
System.out.println(strPath+" 找不到!");
result.append("0");
}
PrintWriter out = response.getWriter();
out.write(result.toString());
out.flush();
out.close();
} }

当我们再次访问编辑页面时,即要加载先前对应的XML文件

主要文件( Actions.js和上述Servlet中get方法)

Servlet在此处省略(上述中已提供源码)

Actions.js源码

 /**
*$id:Action 。JS,V 2015-3-23
*$author Dana丶Li$
*/
/**
*结构对于给定的UI操作的对象。
*编辑函数方法管理
*/
function Actions(editorUi)
{
this.editorUi = editorUi;
this.actions = new Object();
this.init();
};
/**
* 添加默认的函数
*/
Actions.prototype.init = function()
{
var ui = this.editorUi;
var editor = ui.editor;
var graph = editor.graph;
graph.cellsMovable=!0; //设置不可移动
graph.cellsDisconnectable=!0; //设置边不可编辑
graph.cellsResizable=!0; //设置不可改变大小
$.post($("#path").val()+"/SaveToXmlServlet",{"tp":$("#mapTp").val(),"type":"get"},function(text){
if(text=="0"){
alert("拓扑图XML文件加载失败!");
}else{
//保存拓扑图XML模板文件
//example:
//<mxGraphModel grid="0" guides="1" tooltips="1" connect="1" fold="1" page="0" pageScale="1" pageWidth="826" pageHeight="1169">
// <root>
// <mxCell id="0"/>
// <mxCell id="1" parent="0"/>
// <mxCell id="2" value="测试网闸[内端] 通讯:192.168.0.199 业务: 192.168.1.199" style="image;image=stencils/clipart/pic3.png" vertex="1" remark="142588842925033" parent="1">
// <mxGeometry x="236" y="139" width="80" height="80" as="geometry"/>
// </mxCell>
// </root>
//</mxGraphModel>
var xml = text;
var doc = mxUtils.parseXml(xml);
var model = new mxGraphModel();
var codec = new mxCodec(doc);
codec.decode(doc.documentElement, model);
var children = model.getChildren(model.getChildAt(model.getRoot(), 0));
graph.setSelectionCells(editor.graph.importCells(children));
}
}); //文件操作
this.addAction('new', function() { window.open(ui.getUrl());});
this.addAction('open', function()
{
window.openNew = true;
window.openKey = 'open';
ui.openFile();
}); this.addAction('import', function()
{
window.openNew = false;
window.openKey = 'import'; //关闭对话框后打开
window.openFile = new OpenFile(mxUtils.bind(this, function()
{
ui.hideDialog();
})); window.openFile.setConsumer(mxUtils.bind(this, function(xml, filename)
{
try
{
var doc = mxUtils.parseXml(xml);
var model = new mxGraphModel();
var codec = new mxCodec(doc);
codec.decode(doc.documentElement, model); var children = model.getChildren(model.getChildAt(model.getRoot(), 0));
editor.graph.setSelectionCells(editor.graph.importCells(children));
}
catch (e)
{
mxUtils.alert(mxResources.get('invalidOrMissingFile') + ': ' + e.message);
}
})); //如果删除打开文件对话框关闭
ui.showDialog(new OpenDialog(this).container, 300, 180, true, true, function()
{
window.openFile = null;
});
});
this.addAction('save', function() { ui.save(); }, null, null, 'Ctrl+S'); //this.addAction('saveAs', function() { ui.saveFile(true); }, null, null, 'Ctrl+Shift-S');
//this.addAction('export', function() { ui.showDialog(new ExportDialog(ui).container, 300, 200, true, true); }, null, null, 'Ctrl+E');
//this.put('editFile', new Action(mxResources.get('edit'), mxUtils.bind(this, function()
//{
//this.editorUi.showDialog(new EditFileDialog(ui).container, 620, 420, true, true);
//})));
this.addAction('pageSetup', function() { ui.showDialog(new PageSetupDialog(ui).container, 300, 200, true, true); }); //打印
this.addAction('print', function() { ui.showDialog(new PrintDialog(ui).container, 300, 200, true, true); }, null, 'sprite-print', 'Ctrl+P'); this.addAction('preview', function() { mxUtils.show(graph, null, 10, 10); }); //编辑操作
this.addAction('undo', function() { editor.undoManager.undo(); }, null, 'sprite-undo', 'Ctrl+Z');
this.addAction('redo', function() { editor.undoManager.redo(); }, null, 'sprite-redo', 'Ctrl+Y');
this.addAction('cut', function() { mxClipboard.cut(graph); }, null, 'sprite-cut', 'Ctrl+X');
this.addAction('copy', function() { mxClipboard.copy(graph); }, null, 'sprite-copy', 'Ctrl+C');
this.addAction('paste', function() { mxClipboard.paste(graph); }, false, 'sprite-paste', 'Ctrl+V');
this.addAction('delete', function() { graph.removeCells(); }, null, null, 'Delete');
this.addAction('duplicate', function()
{
var s = graph.gridSize;
graph.setSelectionCells(graph.moveCells(graph.getSelectionCells(), s, s, true));
}, null, null, 'Ctrl+D');
this.addAction('selectVertices', function() { graph.selectVertices(); }, null, null, 'Ctrl+Shift+V');
this.addAction('selectEdges', function() { graph.selectEdges(); }, null, null, 'Ctrl+Shift+E');
this.addAction('selectAll', function() { graph.selectAll(); }, null, null, 'Ctrl+A'); //导航行动
this.addAction('home', function() { graph.home(); }, null, null, 'Home');
this.addAction('exitGroup', function() { graph.exitGroup(); }, null, null, 'Page Up');
this.addAction('enterGroup', function() { graph.enterGroup(); }, null, null, 'Page Down');
this.addAction('expand', function() { graph.foldCells(false); }, null, null, 'Enter');
this.addAction('collapse', function() { graph.foldCells(true); }, null, null, 'Backspace'); //安排行动
this.addAction('toFront', function() { graph.orderCells(false); }, null, null, 'Ctrl+F');
this.addAction('toBack', function() { graph.orderCells(true); }, null, null, 'Ctrl+B');
this.addAction('group', function() { graph.setSelectionCell(graph.groupCells(null, 0)); }, null, null, 'Ctrl+G');
this.addAction('ungroup', function() { graph.setSelectionCells(graph.ungroupCells()); }, null, null, 'Ctrl+U');
this.addAction('removeFromGroup', function() { graph.removeCellsFromParent(); });
this.addAction('editLink', function()
{
var cell = graph.getSelectionCell();
var link = graph.getLinkForCell(cell); if (link == null)
{
link = '';
} link = mxUtils.prompt(mxResources.get('enterValue'), link); if (link != null)
{
graph.setLinkForCell(cell, link);
}
});
this.addAction('openLink', function()
{
var cell = graph.getSelectionCell();
var link = graph.getLinkForCell(cell); if (link != null)
{
window.open(link);
}
});
this.addAction('autosize', function()
{
var cells = graph.getSelectionCells(); if (cells != null)
{
graph.getModel().beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
var cell = cells[i]; if (graph.getModel().getChildCount(cell))
{
graph.updateGroupBounds([cell], 20);
}
else
{
graph.updateCellSize(cell);
}
}
}
finally
{
graph.getModel().endUpdate();
}
}
});
this.addAction('rotation', function()
{
var value = '0';
var state = graph.getView().getState(graph.getSelectionCell()); if (state != null)
{
value = state.style[mxConstants.STYLE_ROTATION] || value;
} value = mxUtils.prompt(mxResources.get('enterValue') + ' (' +
mxResources.get('rotation') + ' 0-360)', value); if (value != null)
{
graph.setCellStyles(mxConstants.STYLE_ROTATION, value);
}
});
this.addAction('rotate', function()
{
var cells = graph.getSelectionCells(); if (cells != null)
{
graph.getModel().beginUpdate();
try
{
for (var i = 0; i < cells.length; i++)
{
var cell = cells[i]; if (graph.getModel().isVertex(cell) && graph.getModel().getChildCount(cell) == 0)
{
var geo = graph.getCellGeometry(cell); if (geo != null)
{
//旋转的几何尺寸及位置
geo = geo.clone();
geo.x += geo.width / 2 - geo.height / 2;
geo.y += geo.height / 2 - geo.width / 2;
var tmp = geo.width;
geo.width = geo.height;
geo.height = tmp;
graph.getModel().setGeometry(cell, geo); //方向和进展90度读
var state = graph.view.getState(cell); if (state != null)
{
var dir = state.style[mxConstants.STYLE_DIRECTION] || 'east'/*default*/; if (dir == 'east')
{
dir = 'south';
}
else if (dir == 'south')
{
dir = 'west';
}
else if (dir == 'west')
{
dir = 'north';
}
else if (dir == 'north')
{
dir = 'east';
} graph.setCellStyles(mxConstants.STYLE_DIRECTION, dir, [cell]);
}
}
}
}
}
finally
{
graph.getModel().endUpdate();
}
}
}, null, null, 'Ctrl+R'); //视图的操作
this.addAction('actualSize', function()
{
graph.zoomTo(1);
});
this.addAction('zoomIn', function() { graph.zoomIn(); }, null, null, 'Add');
this.addAction('zoomOut', function() { graph.zoomOut(); }, null, null, 'Subtract');
this.addAction('fitWindow', function() { graph.fit(); }); this.addAction('fitPage', mxUtils.bind(this, function()
{
if (!graph.pageVisible)
{
this.get('pageView').funct();
} var fmt = graph.pageFormat;
var ps = graph.pageScale;
var cw = graph.container.clientWidth - 20;
var ch = graph.container.clientHeight - 20; var scale = Math.floor(100 * Math.min(cw / fmt.width / ps, ch / fmt.height / ps)) / 100;
graph.zoomTo(scale); graph.container.scrollLeft = Math.round(graph.view.translate.x * scale - Math.max(10, (graph.container.clientWidth - fmt.width * ps * scale) / 2));
graph.container.scrollTop = Math.round(graph.view.translate.y * scale - Math.max(10, (graph.container.clientHeight - fmt.height * ps * scale) / 2));
}));
this.addAction('fitPageWidth', mxUtils.bind(this, function()
{
if (!graph.pageVisible)
{
this.get('pageView').funct();
} var fmt = graph.pageFormat;
var ps = graph.pageScale;
var cw = graph.container.clientWidth - 20; var scale = Math.floor(100 * cw / fmt.width / ps) / 100;
graph.zoomTo(scale); graph.container.scrollLeft = Math.round(graph.view.translate.x * scale - Math.max(10, (graph.container.clientWidth - fmt.width * ps * scale) / 2));
graph.container.scrollTop = Math.round(graph.view.translate.y * scale - Math.max(10, (graph.container.clientHeight - fmt.height * ps * scale) / 2));
}));
this.put('customZoom', new Action(mxResources.get('custom'), function()
{
var value = mxUtils.prompt(mxResources.get('enterValue') + ' (%)', parseInt(graph.getView().getScale() * 100)); if (value != null && value.length > 0 && !isNaN(parseInt(value)))
{
graph.zoomTo(parseInt(value) / 100);
}
})); //选择行动
var action = null;
action = this.addAction('grid', function()
{
graph.setGridEnabled(!graph.isGridEnabled());
editor.updateGraphComponents();
}, null, null, 'Ctrl+Shift+G');
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.isGridEnabled(); });
action = this.addAction('guides', function() { graph.graphHandler.guidesEnabled = !graph.graphHandler.guidesEnabled; });
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.graphHandler.guidesEnabled; });
action = this.addAction('tooltips', function()
{
graph.tooltipHandler.setEnabled(!graph.tooltipHandler.isEnabled());
});
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.tooltipHandler.isEnabled(); });
action = this.addAction('navigation', function()
{
graph.foldingEnabled = !graph.foldingEnabled;
graph.view.revalidate();
});
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.foldingEnabled; });
action = this.addAction('scrollbars', function()
{
graph.scrollbars = !graph.scrollbars;
editor.updateGraphComponents(); if (!graph.scrollbars)
{
var t = graph.view.translate;
graph.view.setTranslate(t.x - graph.container.scrollLeft / graph.view.scale, t.y - graph.container.scrollTop / graph.view.scale);
graph.container.scrollLeft = 0;
graph.container.scrollTop = 0;
graph.sizeDidChange();
}
else
{
var dx = graph.view.translate.x;
var dy = graph.view.translate.y; graph.view.translate.x = 0;
graph.view.translate.y = 0;
graph.sizeDidChange();
graph.container.scrollLeft -= Math.round(dx * graph.view.scale);
graph.container.scrollTop -= Math.round(dy * graph.view.scale);
}
}, !mxClient.IS_TOUCH);
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.container.style.overflow == 'auto'; });
action = this.addAction('pageView', mxUtils.bind(this, function()
{
graph.pageVisible = !graph.pageVisible;
graph.pageBreaksVisible = graph.pageVisible;
graph.preferPageSize = graph.pageBreaksVisible;
graph.view.validate();
graph.sizeDidChange(); editor.updateGraphComponents();
editor.outline.update(); if (mxUtils.hasScrollbars(graph.container))
{
if (graph.pageVisible)
{
graph.container.scrollLeft -= 20;
graph.container.scrollTop -= 20;
}
else
{
graph.container.scrollLeft += 20;
graph.container.scrollTop += 20;
}
}
}));
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.pageVisible; });
this.put('pageBackgroundColor', new Action(mxResources.get('backgroundColor'), function()
{
var apply = function(color)
{
graph.background = color;
editor.updateGraphComponents();
}; var cd = new ColorDialog(ui, graph.background || 'none', apply);
ui.showDialog(cd.container, 220, 360, true, false); if (!mxClient.IS_TOUCH)
{
cd.colorInput.focus();
}
}));
action = this.addAction('connect', function()
{
graph.setConnectable(!graph.connectionHandler.isEnabled());
}, null, null, 'Ctrl+Q');
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.connectionHandler.isEnabled(); }); //帮助行为
this.addAction('help', function()
{
var ext = ''; if (mxResources.isLanguageSupported(mxClient.language))
{
ext = '_' + mxClient.language;
} window.open(RESOURCES_PATH + '/help' + ext + '.html');
});
this.put('about', new Action(mxResources.get('about') + ' Graph Editor', function()
{
ui.showDialog(new AboutDialog(ui).container, 320, 280, true, true);
}, null, null, 'F1')); //字体风格的动作
var toggleFontStyle = mxUtils.bind(this, function(key, style)
{
this.addAction(key, function()
{
graph.toggleCellStyleFlags(mxConstants.STYLE_FONTSTYLE, style);
});
}); toggleFontStyle('bold', mxConstants.FONT_BOLD);
toggleFontStyle('italic', mxConstants.FONT_ITALIC);
toggleFontStyle('underline', mxConstants.FONT_UNDERLINE); //颜色动作
this.addAction('fontColor', function() { ui.menus.pickColor(mxConstants.STYLE_FONTCOLOR); });
this.addAction('strokeColor', function() { ui.menus.pickColor(mxConstants.STYLE_STROKECOLOR); });
this.addAction('fillColor', function() { ui.menus.pickColor(mxConstants.STYLE_FILLCOLOR); });
this.addAction('gradientColor', function() { ui.menus.pickColor(mxConstants.STYLE_GRADIENTCOLOR); });
this.addAction('backgroundColor', function() { ui.menus.pickColor(mxConstants.STYLE_LABEL_BACKGROUNDCOLOR); });
this.addAction('borderColor', function() { ui.menus.pickColor(mxConstants.STYLE_LABEL_BORDERCOLOR); }); //格式的行为
this.addAction('shadow', function() { graph.toggleCellStyles(mxConstants.STYLE_SHADOW); });
this.addAction('dashed', function() { graph.toggleCellStyles(mxConstants.STYLE_DASHED); });
this.addAction('rounded', function() { graph.toggleCellStyles(mxConstants.STYLE_ROUNDED); });
this.addAction('style', function()
{
var cells = graph.getSelectionCells(); if (cells != null && cells.length > 0)
{
var model = graph.getModel();
var style = mxUtils.prompt(mxResources.get('enterValue')+ ' (' + mxResources.get('style') + ')',
model.getStyle(cells[0]) || ''); if (style != null)
{
graph.setCellStyle(style, cells);
}
}
});
this.addAction('setAsDefaultEdge', function()
{
var cell = graph.getSelectionCell(); if (cell != null && graph.getModel().isEdge(cell))
{
//采取快照的细胞在调用的时刻
var proto = graph.getModel().cloneCells([cell])[0]; //删除输入/ exitxy风格
var style = proto.getStyle();
style = mxUtils.setStyle(style, mxConstants.STYLE_ENTRY_X, '');
style = mxUtils.setStyle(style, mxConstants.STYLE_ENTRY_Y, '');
style = mxUtils.setStyle(style, mxConstants.STYLE_EXIT_X, '');
style = mxUtils.setStyle(style, mxConstants.STYLE_EXIT_Y, '');
proto.setStyle(style); //使用边缘模板连接预览
graph.connectionHandler.createEdgeState = function(me)
{
return graph.view.createState(proto);
}; //创建新的连接边缘模板
graph.connectionHandler.factoryMethod = function()
{
return graph.cloneCells([proto])[0];
};
}
});
this.addAction('image', function()
{
function updateImage(value, w, h)
{
var select = null;
var cells = graph.getSelectionCells(); graph.getModel().beginUpdate();
try
{
//没有选中单元格
if (cells.length == 0)
{
var gs = graph.getGridSize();
cells = [graph.insertVertex(graph.getDefaultParent(), null, '', gs, gs, w, h)];
select = cells;
} graph.setCellStyles(mxConstants.STYLE_IMAGE, value, cells);
graph.setCellStyles(mxConstants.STYLE_SHAPE, 'image', cells); if (graph.getSelectionCount() == 1)
{
if (w != null && h != null)
{
var cell = cells[0];
var geo = graph.getModel().getGeometry(cell); if (geo != null)
{
geo = geo.clone();
geo.width = w;
geo.height = h;
graph.getModel().setGeometry(cell, geo);
}
}
}
}
finally
{
graph.getModel().endUpdate();
} if (select != null)
{
graph.setSelectionCells(select);
graph.scrollCellToVisible(select[0]);
}
}; var value = '';
var state = graph.getView().getState(graph.getSelectionCell()); if (state != null)
{
value = state.style[mxConstants.STYLE_IMAGE] || value;
} value = mxUtils.prompt(mxResources.get('enterValue') + ' (' + mxResources.get('url') + ')', value); if (value != null)
{
if (value.length > 0)
{
var img = new Image(); img.onload = function()
{
updateImage(value, img.width, img.height);
};
img.onerror = function()
{
mxUtils.alert(mxResources.get('fileNotFound'));
};
img.src = value;
}
}
});
}; /**
* 寄存器的作用在给定的名称.
*/
Actions.prototype.addAction = function(key, funct, enabled, iconCls, shortcut)
{
return this.put(key, new Action(mxResources.get(key), funct, enabled, iconCls, shortcut));
}; /**
* 寄存器的作用在给定的名称。
*/
Actions.prototype.put = function(name, action)
{
this.actions[name] = action; return action;
}; /**
* 返回给定名称或空如果没有这样的行动存在的动作。
*/
Actions.prototype.get = function(name)
{
return this.actions[name];
}; /**
* 对于给定的参数的一种新的活动构造。
*/
function Action(label, funct, enabled, iconCls, shortcut)
{
mxEventSource.call(this);
this.label = label;
this.funct = funct;
this.enabled = (enabled != null) ? enabled : true;
this.iconCls = iconCls;
this.shortcut = shortcut;
}; //行动继承mxeventsource
mxUtils.extend(Action, mxEventSource); Action.prototype.setEnabled = function(value)
{
if (this.enabled != value)
{
this.enabled = value;
this.fireEvent(new mxEventObject('stateChanged'));
}
}; /**
*套动作启用状态statechanged事件。
*/
Action.prototype.setToggleAction = function(value)
{
this.toggleAction = value;
}; /**
*套动作启用状态statechanged事件。
*/
Action.prototype.setSelectedCallback = function(funct)
{
this.selectedCallback = funct;
}; /**
* 套动作启用状态statechanged事件。
*/
Action.prototype.isSelected = function()
{
return this.selectedCallback();
};

工具栏~Sidebar.js

如:图标A区 ,图标B区的控制

源码:

 /**
*$id:Action 。JS,V 2015-3-23
*$author Dana丶Li$
*/
/**
* Construcs a new sidebar for the given editor.
*/
function Sidebar(editorUi, container)
{
this.editorUi = editorUi;
this.container = container;
this.palettes = new Object();
this.showTooltips = true;
this.graph = new Graph(document.createElement('div'), null, null, this.editorUi.editor.graph.getStylesheet());
this.graph.foldingEnabled = false;
this.graph.autoScroll = false;
this.graph.setTooltips(false);
this.graph.setConnectable(false);
this.graph.resetViewOnRootChange = false;
this.graph.view.setTranslate(this.thumbBorder, this.thumbBorder);
this.graph.setEnabled(false); // Workaround for VML rendering in IE8 standards mode where the container must be in the DOM
// so that VML references can be restored via document.getElementById in mxShape.init.
if (document.documentMode == 8)
{
document.body.appendChild(this.graph.container);
} // Workaround for no rendering in 0 coordinate in FF 10
if (this.shiftThumbs)
{
this.graph.view.canvas.setAttribute('transform', 'translate(1, 1)');
} if (!mxClient.IS_TOUCH)
{
mxEvent.addListener(document, 'mouseup', mxUtils.bind(this, function()
{
this.showTooltips = true;
})); // Enables tooltips after scroll
mxEvent.addListener(container, 'scroll', mxUtils.bind(this, function()
{
this.showTooltips = true;
})); mxEvent.addListener(document, 'mousedown', mxUtils.bind(this, function()
{
this.showTooltips = false;
this.hideTooltip();
})); mxEvent.addListener(document, 'mousemove', mxUtils.bind(this, function(evt)
{
var src = mxEvent.getSource(evt); while (src != null)
{
if (src == this.currentElt)
{
return;
} src = src.parentNode;
} this.hideTooltip();
})); // Handles mouse leaving the window
mxEvent.addListener(document, 'mouseout', mxUtils.bind(this, function(evt)
{
if (evt.toElement == null && evt.relatedTarget == null)
{
this.hideTooltip();
}
}));
} this.init(); //图像预fetches提示
new Image().src = IMAGE_PATH + '/tooltip.png';
}; /**
* 将所有工具栏的侧边栏。
*/
Sidebar.prototype.init = function()
{
var dir = STENCIL_PATH; //this.addGeneralPalette(true);
//this.addUmlPalette(true);
//this.addBpmnPalette(dir, false);
//this.addStencilPalette('flowchart', 'Flowchart', dir + '/flowchart.xml',';fillColor=#ffffff;strokeColor=#000000;strokeWidth=2');
//this.addStencilPalette('basic', mxResources.get('basic'), dir + '/basic.xml',';fillColor=#ffffff;strokeColor=#000000;strokeWidth=2');
//this.addStencilPalette('arrows', mxResources.get('arrows'), dir + '/arrows.xml',';fillColor=#ffffff;strokeColor=#000000;strokeWidth=2'); this.addImagePalette('clipart', mxResources.get('clipart'), dir + '/clipart/', '_128x128.png',
[ 'colud', 'Firewall_02', 'Server_Tower', 'serverDB', 'serverAuth',
'serverPrint', 'serverEmail', 'serverDisk', 'Router_Icon', 'routerFirewall', 'route1', 'atm', 'police',
'accessServer','SIP', 'sipProxy', 'ITP', 'CA', '3U', 'ipv6Route',
'3layer', 'pbx', 'IDS', 'actionCheck', 'gateWayVPN', 'server1','server2','normalServer','IPSAN','H3Cswitch']); this.addImagePalette('clipartB', mxResources.get('clipartB'), dir + '/clipart/', '.png',
[ 'pic1','pic2','pic3','pic4','pic5','pic6','pic7','pic8','pic9','pic10','pic11','pic12','pic13','pic14','pic15']); }; /**
* 指定工具提示应该是可见的。默认的是真的。
*/
Sidebar.prototype.enableTooltips = !mxClient.IS_TOUCH; /**
* 将缩略图1像素。
*/
Sidebar.prototype.shiftThumbs = mxClient.IS_SVG || document.documentMode == 8; /**
* 指定工具提示的延迟。默认是16像素。
*/
Sidebar.prototype.tooltipBorder = 16; /**
* 指定工具提示的延迟。默认是2像素。
*/
Sidebar.prototype.thumbBorder = 2; /**
* Specifies the delay for the tooltip. Default is 300 ms.
*/
Sidebar.prototype.tooltipDelay = 300; /**
* Specifies if edges should be used as templates if clicked. Default is true.
*/
Sidebar.prototype.installEdges = true; /**
* Specifies the URL of the gear image.
*/
Sidebar.prototype.gearImage = STENCIL_PATH + '/clipart/Gear_128x128.png'; /**
* Specifies the width of the thumbnails.
*/
Sidebar.prototype.thumbWidth = 26; /**
* Specifies the height of the thumbnails.
*/
Sidebar.prototype.thumbHeight = 26; /**
* Adds all palettes to the sidebar.
*/
Sidebar.prototype.showTooltip = function(elt, cells)
{
if (this.enableTooltips && this.showTooltips)
{
if (this.currentElt != elt)
{
if (this.thread != null)
{
window.clearTimeout(this.thread);
this.thread = null;
} var show = mxUtils.bind(this, function()
{
// Workaround for off-screen text rendering in IE
var old = mxText.prototype.getTableSize; if (this.graph.dialect != mxConstants.DIALECT_SVG)
{
mxText.prototype.getTableSize = function(table)
{
var oldParent = table.parentNode; document.body.appendChild(table);
var size = new mxRectangle(0, 0, table.offsetWidth, table.offsetHeight);
oldParent.appendChild(table); return size;
};
} // Lazy creation of the DOM nodes and graph instance
if (this.tooltip == null)
{
this.tooltip = document.createElement('div');
this.tooltip.className = 'geSidebarTooltip';
document.body.appendChild(this.tooltip); this.graph2 = new Graph(this.tooltip, null, null, this.editorUi.editor.graph.getStylesheet());
this.graph2.view.setTranslate(this.tooltipBorder, this.tooltipBorder);
this.graph2.resetViewOnRootChange = false;
this.graph2.foldingEnabled = false;
this.graph2.autoScroll = false;
this.graph2.setTooltips(false);
this.graph2.setConnectable(false);
this.graph2.setEnabled(false); this.tooltipImage = mxUtils.createImage(IMAGE_PATH + '/tooltip.png');
this.tooltipImage.style.position = 'absolute';
this.tooltipImage.style.width = '14px';
this.tooltipImage.style.height = '27px'; document.body.appendChild(this.tooltipImage);
} this.graph2.model.clear();
this.graph2.addCells(cells); var bounds = this.graph2.getGraphBounds();
var width = bounds.x + bounds.width + this.tooltipBorder;
var height = bounds.y + bounds.height + this.tooltipBorder; if (mxClient.IS_QUIRKS)
{
width += 4;
height += 4;
} this.tooltip.style.display = 'block';
this.tooltip.style.overflow = 'visible';
this.tooltipImage.style.visibility = 'visible';
this.tooltip.style.width = width + 'px';
this.tooltip.style.height = height + 'px'; var left = this.container.clientWidth + this.editorUi.splitSize + 3;
var top = Math.max(0, (this.container.offsetTop + elt.offsetTop - this.container.scrollTop - height / 2 + 16)); // Workaround for ignored position CSS style in IE9
// (changes to relative without the following line)
this.tooltip.style.position = 'absolute';
this.tooltip.style.left = left + 'px';
this.tooltip.style.top = top + 'px';
this.tooltipImage.style.left = (left - 13) + 'px';
this.tooltipImage.style.top = (top + height / 2 - 13) + 'px'; mxText.prototype.getTableSize = old;
}); if (this.tooltip != null && this.tooltip.style.display != 'none')
{
show();
}
else
{
this.thread = window.setTimeout(show, this.tooltipDelay);
} this.currentElt = elt;
}
}
}; /**
* Hides the current tooltip.
*/
Sidebar.prototype.hideTooltip = function()
{
if (this.thread != null)
{
window.clearTimeout(this.thread);
this.thread = null;
} if (this.tooltip != null)
{
this.tooltip.style.display = 'none';
this.tooltipImage.style.visibility = 'hidden';
this.currentElt = null;
}
}; /**
* Adds the general palette to the sidebar.
*/
Sidebar.prototype.addGeneralPalette = function(expand)
{
this.addPalette('general', mxResources.get('general'), expand || true, mxUtils.bind(this, function(content)
{
content.appendChild(this.createVertexTemplate('swimlane', 200, 200, 'Container'));
content.appendChild(this.createVertexTemplate('swimlane;horizontal=0', 200, 200, 'Pool'));
content.appendChild(this.createVertexTemplate('text', 40, 26, 'Text'));
content.appendChild(this.createVertexTemplate('icon;image=' + this.gearImage, 60, 60, 'Image'));
content.appendChild(this.createVertexTemplate('label;image=' + this.gearImage, 140, 60, 'Label'));
content.appendChild(this.createVertexTemplate(null, 120, 60));
content.appendChild(this.createVertexTemplate('rounded=1', 120, 60));
content.appendChild(this.createVertexTemplate('ellipse', 80, 80));
content.appendChild(this.createVertexTemplate('ellipse;shape=doubleEllipse', 80, 80));
content.appendChild(this.createVertexTemplate('triangle', 60, 80));
content.appendChild(this.createVertexTemplate('rhombus', 80, 80));
content.appendChild(this.createVertexTemplate('shape=hexagon', 120, 80));
content.appendChild(this.createVertexTemplate('shape=actor;verticalLabelPosition=bottom;verticalAlign=top', 40, 60));
content.appendChild(this.createVertexTemplate('ellipse;shape=cloud', 120, 80));
content.appendChild(this.createVertexTemplate('shape=cylinder', 60, 80));
content.appendChild(this.createVertexTemplate('line', 160, 10));
content.appendChild(this.createVertexTemplate('line;direction=south', 10, 160));
content.appendChild(this.createVertexTemplate('shape=xor', 60, 80));
content.appendChild(this.createVertexTemplate('shape=or', 60, 80));
content.appendChild(this.createVertexTemplate('shape=step', 120, 80));
content.appendChild(this.createVertexTemplate('shape=tape', 120, 100));
content.appendChild(this.createVertexTemplate('shape=cube', 120, 80));
content.appendChild(this.createVertexTemplate('shape=note', 80, 100));
content.appendChild(this.createVertexTemplate('shape=folder', 120, 120));
content.appendChild(this.createVertexTemplate('shape=card', 60, 80));
content.appendChild(this.createVertexTemplate('shape=plus', 20, 20)); content.appendChild(this.createEdgeTemplate('edgeStyle=none;endArrow=none;', 100, 100));
content.appendChild(this.createEdgeTemplate('edgeStyle=none', 100, 100));
content.appendChild(this.createEdgeTemplate('edgeStyle=elbowEdgeStyle;elbow=horizontal', 100, 100));
content.appendChild(this.createEdgeTemplate('edgeStyle=elbowEdgeStyle;elbow=vertical', 100, 100));
content.appendChild(this.createEdgeTemplate('edgeStyle=entityRelationEdgeStyle', 100, 100));
content.appendChild(this.createEdgeTemplate('edgeStyle=segmentEdgeStyle', 100, 100));
content.appendChild(this.createEdgeTemplate('edgeStyle=orthogonalEdgeStyle', 100, 100));
content.appendChild(this.createEdgeTemplate('shape=link', 100, 100));
content.appendChild(this.createEdgeTemplate('arrow', 100, 100));
}));
}; /**
* Adds the general palette to the sidebar.
*/
Sidebar.prototype.addUmlPalette = function(expand)
{
this.addPalette('uml', 'UML', expand || false, mxUtils.bind(this, function(content)
{
content.appendChild(this.createVertexTemplate('', 110, 50, 'Object')); var classCell = new mxCell('<p style="margin:0px;margin-top:4px;text-align:center;">' +
'<b>Class</b></p>' +
'<hr/><div style="height:2px;"></div><hr/>', new mxGeometry(0, 0, 140, 60),
'verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1');
classCell.vertex = true;
content.appendChild(this.createVertexTemplateFromCells([classCell], 140, 60)); var classCell = new mxCell('<p style="margin:0px;margin-top:4px;text-align:center;">' +
'<b>Class</b></p>' +
'<hr/><p style="margin:0px;margin-left:4px;">+ field: Type</p><hr/>' +
'<p style="margin:0px;margin-left:4px;">+ method(): Type</p>', new mxGeometry(0, 0, 160, 90),
'verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1');
classCell.vertex = true;
content.appendChild(this.createVertexTemplateFromCells([classCell], 160, 90)); var classCell = new mxCell('<p style="margin:0px;margin-top:4px;text-align:center;">' +
'<i>&lt;&lt;Interface&gt;&gt;</i><br/><b>Interface</b></p>' +
'<hr/><p style="margin:0px;margin-left:4px;">+ field1: Type<br/>' +
'+ field2: Type</p>' +
'<hr/><p style="margin:0px;margin-left:4px;">' +
'+ method1(Type): Type<br/>' +
'+ method2(Type, Type): Type</p>', new mxGeometry(0, 0, 190, 140),
'verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1');
classCell.vertex = true;
content.appendChild(this.createVertexTemplateFromCells([classCell], 190, 140)); var classCell = new mxCell('Module', new mxGeometry(0, 0, 120, 60),
'shape=component;align=left;spacingLeft=36');
classCell.vertex = true; content.appendChild(this.createVertexTemplateFromCells([classCell], 120, 60)); var classCell = new mxCell('&lt;&lt;component&gt;&gt;<br/><b>Component</b>', new mxGeometry(0, 0, 180, 90),
'overflow=fill;html=1');
classCell.vertex = true;
var classCell1 = new mxCell('', new mxGeometry(1, 0, 20, 20), 'shape=component;jettyWidth=8;jettyHeight=4;');
classCell1.vertex = true;
classCell1.connectable = false;
classCell1.geometry.relative = true;
classCell1.geometry.offset = new mxPoint(-30, 10);
classCell.insert(classCell1); content.appendChild(this.createVertexTemplateFromCells([classCell], 180, 90)); var classCell = new mxCell('<p style="margin:0px;margin-top:6px;text-align:center;"><b>Component</b></p>' +
'<hr/><p style="margin:0px;margin-left:8px;">+ Attribute1: Type<br/>+ Attribute2: Type</p>', new mxGeometry(0, 0, 180, 90),
'verticalAlign=top;align=left;overflow=fill;html=1');
classCell.vertex = true;
var classCell1 = new mxCell('', new mxGeometry(1, 0, 20, 20), 'shape=component;jettyWidth=8;jettyHeight=4;');
classCell1.vertex = true;
classCell1.connectable = false;
classCell1.geometry.relative = true;
classCell1.geometry.offset = new mxPoint(-23, 3);
classCell.insert(classCell1); content.appendChild(this.createVertexTemplateFromCells([classCell], 180, 90)); content.appendChild(this.createVertexTemplate('shape=lollipop;direction=south;', 30, 10)); var cardCell = new mxCell('Block', new mxGeometry(0, 0, 180, 120),
'verticalAlign=top;align=left;spacingTop=8;spacingLeft=2;spacingRight=12;shape=cube;size=10;direction=south;fontStyle=4;');
cardCell.vertex = true;
content.appendChild(this.createVertexTemplateFromCells([cardCell], 180, 120)); content.appendChild(this.createVertexTemplate('shape=folder;fontStyle=1;spacingTop=10;tabWidth=40;tabHeight=14;tabPosition=left;', 70, 50,
'package')); var classCell = new mxCell('<p style="margin:0px;margin-top:4px;text-align:center;text-decoration:underline;">' +
'<b>Object:Type</b></p><hr/>' +
'<p style="margin:0px;margin-left:8px;">field1 = value1<br/>field2 = value2<br>field3 = value3</p>',
new mxGeometry(0, 0, 160, 90),
'verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1');
classCell.vertex = true;
content.appendChild(this.createVertexTemplateFromCells([classCell], 160, 90)); var tableCell = new mxCell('<table cellpadding="5" style="font-size:9pt;border:none;border-collapse:collapse;width:100%;">' +
'<tr><td colspan="2" style="border:1px solid gray;background:#e4e4e4;">Tablename</td></tr>' +
'<tr><td style="border:1px solid gray;">PK</td><td style="border:1px solid gray;">uniqueId</td></tr>' +
'<tr><td style="border:1px solid gray;">FK1</td><td style="border:1px solid gray;">foreignKey</td></tr>' +
'<tr><td style="border:1px solid gray;"></td><td style="border:1px solid gray;">fieldname</td></tr>' +
'</table>', new mxGeometry(0, 0, 180, 99), 'verticalAlign=top;align=left;overflow=fill;html=1');
tableCell.vertex = true;
content.appendChild(this.createVertexTemplateFromCells([tableCell], 180, 99)); content.appendChild(this.createVertexTemplate('shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top', 40, 80, 'Actor'));
content.appendChild(this.createVertexTemplate('ellipse', 140, 70, 'Use Case')); var cardCell = new mxCell('', new mxGeometry(0, 0, 30, 30),
'ellipse;shape=startState;fillColor=#000000;strokeColor=#ff0000;');
cardCell.vertex = true; var assoc2 = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=horizontal;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;');
assoc2.geometry.setTerminalPoint(new mxPoint(15, 70), false);
assoc2.edge = true; cardCell.insertEdge(assoc2, true); content.appendChild(this.createVertexTemplateFromCells([cardCell, assoc2], 30, 30)); var cardCell = new mxCell('Activity', new mxGeometry(0, 0, 120, 40),
'rounded=1;arcSize=40;fillColor=#ffffc0;strokeColor=#ff0000;');
cardCell.vertex = true; var assoc2 = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=horizontal;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;');
assoc2.geometry.setTerminalPoint(new mxPoint(60, 80), false);
assoc2.edge = true; cardCell.insertEdge(assoc2, true); content.appendChild(this.createVertexTemplateFromCells([cardCell, assoc2], 120, 40)); var cardCell = new mxCell('<div style="margin-top:8px;"><b>Composite State</b><hr/>Subtitle</div>', new mxGeometry(0, 0, 160, 60),
'rounded=1;arcSize=40;overflow=fill;html=1;verticalAlign=top;fillColor=#ffffc0;strokeColor=#ff0000;');
cardCell.vertex = true; var assoc2 = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=horizontal;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;');
assoc2.geometry.setTerminalPoint(new mxPoint(80, 100), false);
assoc2.edge = true; cardCell.insertEdge(assoc2, true); content.appendChild(this.createVertexTemplateFromCells([cardCell, assoc2], 160, 60)); var cardCell = new mxCell('Condition', new mxGeometry(0, 0, 80, 40),
'rhombus;fillColor=#ffffc0;strokeColor=#ff0000;');
cardCell.vertex = true; var assoc1 = new mxCell('no', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=horizontal;align=left;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;');
assoc1.geometry.setTerminalPoint(new mxPoint(120, 20), false);
assoc1.geometry.relative = true;
assoc1.geometry.x = -1;
assoc1.edge = true; cardCell.insertEdge(assoc1, true); var assoc2 = new mxCell('yes', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=horizontal;align=left;verticalAlign=top;endArrow=open;endSize=8;strokeColor=#ff0000;');
assoc2.geometry.setTerminalPoint(new mxPoint(40, 80), false);
assoc2.geometry.relative = true;
assoc2.geometry.x = -1;
assoc2.edge = true; cardCell.insertEdge(assoc2, true); content.appendChild(this.createVertexTemplateFromCells([cardCell, assoc1, assoc2], 80, 40)); var cardCell = new mxCell('', new mxGeometry(0, 0, 200, 10),
'shape=line;strokeWidth=6;strokeColor=#ff0000;');
cardCell.vertex = true; var assoc2 = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=horizontal;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;');
assoc2.geometry.setTerminalPoint(new mxPoint(100, 50), false);
assoc2.edge = true; cardCell.insertEdge(assoc2, true); content.appendChild(this.createVertexTemplateFromCells([cardCell, assoc2], 200, 10)); content.appendChild(this.createVertexTemplate('ellipse;shape=endState;fillColor=#000000;strokeColor=#ff0000', 30, 30)); var classCell1 = new mxCell(':Object', new mxGeometry(0, 0, 100, 50));
classCell1.vertex = true; var classCell2 = new mxCell('', new mxGeometry(40, 50, 20, 240), 'shape=line;direction=north;dashed=1');
classCell2.vertex = true; content.appendChild(this.createVertexTemplateFromCells([classCell1, classCell2], 100, 290)); var classCell1 = new mxCell('', new mxGeometry(100, 0, 20, 70));
classCell1.vertex = true; var assoc1 = new mxCell('invoke', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=vertical;verticalAlign=bottom;endArrow=block;');
assoc1.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc1.edge = true; classCell1.insertEdge(assoc1, false); content.appendChild(this.createVertexTemplateFromCells([classCell1, assoc1], 120, 70)); var classCell1 = new mxCell('', new mxGeometry(100, 0, 20, 70));
classCell1.vertex = true; var assoc1 = new mxCell('invoke', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=vertical;verticalAlign=bottom;endArrow=block;');
assoc1.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc1.edge = true; classCell1.insertEdge(assoc1, false); var assoc2 = new mxCell('return', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=vertical;verticalAlign=bottom;dashed=1;endArrow=open;endSize=8;');
assoc2.geometry.setTerminalPoint(new mxPoint(0, 70), false);
assoc2.edge = true; classCell1.insertEdge(assoc2, true); var assoc3 = new mxCell('invoke', new mxGeometry(0, 0, 0, 0), 'edgeStyle=elbowEdgeStyle;elbow=vertical;align=left;endArrow=open;');
assoc3.edge = true; classCell1.insertEdge(assoc3, true);
classCell1.insertEdge(assoc3, false); content.appendChild(this.createVertexTemplateFromCells([classCell1, assoc1, assoc2, assoc3], 120, 70)); var assoc = new mxCell('name', new mxGeometry(0, 0, 0, 0), 'endArrow=block;endFill=1;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=top;');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.geometry.relative = true;
assoc.geometry.x = -1;
assoc.edge = true; var sourceLabel = new mxCell('1', new mxGeometry(-1, 0, 0, 0), 'resizable=0;align=left;verticalAlign=bottom;labelBackgroundColor=#ffffff;fontSize=10');
sourceLabel.geometry.relative = true;
sourceLabel.setConnectable(false);
sourceLabel.vertex = true;
assoc.insert(sourceLabel); content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=none;edgeStyle=orthogonalEdgeStyle;');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; var sourceLabel = new mxCell('parent', new mxGeometry(-1, 0, 0, 0), 'resizable=0;align=left;verticalAlign=bottom;labelBackgroundColor=#ffffff;fontSize=10');
sourceLabel.geometry.relative = true;
sourceLabel.setConnectable(false);
sourceLabel.vertex = true;
assoc.insert(sourceLabel); var targetLabel = new mxCell('child', new mxGeometry(1, 0, 0, 0), 'resizable=0;align=right;verticalAlign=bottom;labelBackgroundColor=#ffffff;fontSize=10');
targetLabel.geometry.relative = true;
targetLabel.setConnectable(false);
targetLabel.vertex = true;
assoc.insert(targetLabel); content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('1', new mxGeometry(0, 0, 0, 0), 'endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=bottom;');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.geometry.relative = true;
assoc.geometry.x = -1;
assoc.edge = true; content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('Relation', new mxGeometry(0, 0, 0, 0), 'endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; var sourceLabel = new mxCell('0..n', new mxGeometry(-1, 0, 0, 0), 'resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10');
sourceLabel.geometry.relative = true;
sourceLabel.setConnectable(false);
sourceLabel.vertex = true;
assoc.insert(sourceLabel); var targetLabel = new mxCell('1', new mxGeometry(1, 0, 0, 0), 'resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10');
targetLabel.geometry.relative = true;
targetLabel.setConnectable(false);
targetLabel.vertex = true;
assoc.insert(targetLabel); content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('Use', new mxGeometry(0, 0, 0, 0), 'endArrow=open;endSize=12;dashed=1');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('Extends', new mxGeometry(0, 0, 0, 0), 'endArrow=block;endSize=16;endFill=0;dashed=1');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=block;startArrow=block;endFill=1;startFill=1');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0));
}));
}; /**
* Adds the BPMN library to the sidebar.
*/
Sidebar.prototype.addBpmnPalette = function(dir, expand)
{
this.addStencilPalette('bpmn', 'BPMN', dir + '/bpmn.xml',
';fillColor=#ffffff;strokeColor=#000000;perimeter=ellipsePerimeter;',
['Cancel', 'Error', 'Link', 'Message', 'Compensation', 'Multiple', 'Rule', 'Timer'],
function(content)
{
content.appendChild(this.createVertexTemplate('swimlane;horizontal=0;', 300, 160, 'Pool')); var classCell = new mxCell('Process', new mxGeometry(0, 0, 140, 60),
'rounded=1');
classCell.vertex = true;
var classCell1 = new mxCell('', new mxGeometry(1, 1, 30, 30), 'shape=mxgraph.bpmn.timer_start;perimeter=ellipsePerimeter;');
classCell1.vertex = true;
classCell1.geometry.relative = true;
classCell1.geometry.offset = new mxPoint(-40, -15);
classCell.insert(classCell1); content.appendChild(this.createVertexTemplateFromCells([classCell], 140, 60)); var classCell = new mxCell('Process', new mxGeometry(0, 0, 140, 60),
'rounded=1');
classCell.vertex = true;
var classCell1 = new mxCell('', new mxGeometry(0.5, 1, 12, 12), 'shape=plus');
classCell1.vertex = true;
classCell1.connectable = false;
classCell1.geometry.relative = true;
classCell1.geometry.offset = new mxPoint(-6, -12);
classCell.insert(classCell1); content.appendChild(this.createVertexTemplateFromCells([classCell], 140, 60)); var classCell = new mxCell('Process', new mxGeometry(0, 0, 140, 60),
'rounded=1');
classCell.vertex = true;
var classCell1 = new mxCell('', new mxGeometry(0, 0, 20, 14), 'shape=message');
classCell1.vertex = true;
classCell1.connectable = false;
classCell1.geometry.relative = true;
classCell1.geometry.offset = new mxPoint(5, 5);
classCell.insert(classCell1); content.appendChild(this.createVertexTemplateFromCells([classCell], 140, 60)); var classCell = new mxCell('', new mxGeometry(0, 0, 60, 40), 'shape=message');
classCell.vertex = true; content.appendChild(this.createEdgeTemplateFromCells([classCell], 60, 40)); var assoc = new mxCell('Sequence', new mxGeometry(0, 0, 0, 0), 'endArrow=block;endFill=1;endSize=6');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('Default', new mxGeometry(0, 0, 0, 0), 'startArrow=dash;startSize=8;endArrow=block;endFill=1;endSize=6');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('Conditional', new mxGeometry(0, 0, 0, 0), 'startArrow=diamondThin;startFill=0;startSize=14;endArrow=block;endFill=1;endSize=6');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('', new mxGeometry(0, 0, 0, 0), 'startArrow=oval;startFill=0;startSize=7;endArrow=block;endFill=0;endSize=10;dashed=1');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('', new mxGeometry(0, 0, 0, 0), 'startArrow=oval;startFill=0;startSize=7;endArrow=block;endFill=0;endSize=10;dashed=1');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; var sourceLabel = new mxCell('', new mxGeometry(0, 0, 20, 14), 'shape=message');
sourceLabel.geometry.relative = true;
sourceLabel.setConnectable(false);
sourceLabel.vertex = true;
sourceLabel.geometry.offset = new mxPoint(-10, -7);
assoc.insert(sourceLabel); content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0)); var assoc = new mxCell('', new mxGeometry(0, 0, 0, 0), 'shape=link');
assoc.geometry.setTerminalPoint(new mxPoint(0, 0), true);
assoc.geometry.setTerminalPoint(new mxPoint(160, 0), false);
assoc.edge = true; content.appendChild(this.createEdgeTemplateFromCells([assoc], 160, 0));
}, 0.5);
}; /**
* Creates and returns the given title element.
*/
Sidebar.prototype.createTitle = function(label)
{
var elt = document.createElement('a');
elt.setAttribute('href', 'javascript:void(0);');
elt.className = 'geTitle';
mxUtils.write(elt, label); return elt;
}; /**
* Creates a thumbnail for the given cells.
*/
Sidebar.prototype.createThumb = function(cells, width, height, parent)
{
// Workaround for off-screen text rendering in IE
var old = mxText.prototype.getTableSize; if (this.graph.dialect != mxConstants.DIALECT_SVG)
{
mxText.prototype.getTableSize = function(table)
{
var oldParent = table.parentNode; document.body.appendChild(table);
var size = new mxRectangle(0, 0, table.offsetWidth, table.offsetHeight);
oldParent.appendChild(table); return size;
};
} var prev = mxImageShape.prototype.preserveImageAspect;
mxImageShape.prototype.preserveImageAspect = false; this.graph.view.rendering = false;
this.graph.view.setScale(1);
this.graph.addCells(cells);
var bounds = this.graph.getGraphBounds(); var corr = (this.shiftThumbs) ? this.thumbBorder + 1 : this.thumbBorder;
var s = Math.min((width - 1) / (bounds.x + bounds.width + corr),
(height - 1) / (bounds.y + bounds.height + corr));
this.graph.view.setScale(s);
this.graph.view.rendering = true;
this.graph.refresh();
mxImageShape.prototype.preserveImageAspect = prev; bounds = this.graph.getGraphBounds();
var dx = Math.max(0, Math.floor((width - bounds.width) / 2));
var dy = Math.max(0, Math.floor((height - bounds.height) / 2)); var node = null; // For supporting HTML labels in IE9 standards mode the container is cloned instead
if (this.graph.dialect == mxConstants.DIALECT_SVG && !mxClient.IS_IE)
{
node = this.graph.view.getCanvas().ownerSVGElement.cloneNode(true);
}
// Workaround for VML rendering in IE8 standards mode
else if (document.documentMode == 8)
{
node = this.graph.container.cloneNode(false);
node.innerHTML = this.graph.container.innerHTML;
}
else
{
node = this.graph.container.cloneNode(true);
} this.graph.getModel().clear(); // Outer dimension is (32, 32)
var dd = (this.shiftThumbs) ? 2 : 3;
node.style.position = 'relative';
node.style.overflow = 'visible';
node.style.cursor = 'pointer';
node.style.left = (dx + dd) + 'px';
node.style.top = (dy + dd) + 'px';
node.style.width = width + 'px';
node.style.height = height + 'px'; parent.appendChild(node);
mxText.prototype.getTableSize = old;
}; /**
* Creates and returns a new palette item for the given image.
*/
Sidebar.prototype.createItem = function(cells)
{
var elt = document.createElement('a');
elt.setAttribute('href', 'javascript:void(0);');
elt.className = 'geItem'; // Blocks default click action
mxEvent.addListener(elt, 'click', function(evt)
{
mxEvent.consume(evt);
}); this.createThumb(cells, this.thumbWidth, this.thumbHeight, elt); return elt;
}; /**
* Creates a drop handler for inserting the given cells.
*/
Sidebar.prototype.createDropHandler = function(cells, allowSplit)
{
return function(graph, evt, target, x, y)
{
cells = graph.getImportableCells(cells); if (cells.length > 0)
{
var validDropTarget = (target != null) ?
graph.isValidDropTarget(target, cells, evt) : false;
var select = null; if (target != null && !validDropTarget)
{
target = null;
} // Splits the target edge or inserts into target group
if (allowSplit && graph.isSplitEnabled() && graph.isSplitTarget(target, cells, evt))
{
graph.splitEdge(target, cells, null, x, y);
select = cells;
}
else if (cells.length > 0)
{
select = graph.importCells(cells, x, y, target);
} if (select != null && select.length > 0)
{
graph.scrollCellToVisible(select[0]);
graph.setSelectionCells(select);
}
}
};
}; /**
* Creates and returns a preview element for the given width and height.
*/
Sidebar.prototype.createDragPreview = function(width, height)
{
var elt = document.createElement('div');
elt.style.border = '1px dashed black';
elt.style.width = width + 'px';
elt.style.height = height + 'px'; return elt;
}; /**
* Creates a drag source for the given element.
*/
Sidebar.prototype.createDragSource = function(elt, dropHandler, preview)
{
var dragSource = mxUtils.makeDraggable(elt, this.editorUi.editor.graph, dropHandler,
preview, 0, 0, this.editorUi.editor.graph.autoscroll, true, true); // Allows drop into cell only if target is a valid root
dragSource.getDropTarget = function(graph, x, y)
{
var target = mxDragSource.prototype.getDropTarget.apply(this, arguments); if (!graph.isValidRoot(target))
{
target = null;
} return target;
}; return dragSource;
}; /**
* Adds a handler for inserting the cell with a single click.
*/
Sidebar.prototype.addClickHandler = function(elt, ds)
{
var graph = this.editorUi.editor.graph;
var first = null; var md = (mxClient.IS_TOUCH) ? 'touchstart' : 'mousedown';
mxEvent.addListener(elt, md, function(evt)
{
first = new mxPoint(mxEvent.getClientX(evt), mxEvent.getClientY(evt));
}); var oldMouseUp = ds.mouseUp;
ds.mouseUp = function(evt)
{
if (!mxEvent.isPopupTrigger(evt) && this.currentGraph == null && first != null)
{
var tol = graph.tolerance; if (Math.abs(first.x - mxEvent.getClientX(evt)) <= tol &&
Math.abs(first.y - mxEvent.getClientY(evt)) <= tol)
{
var gs = graph.getGridSize();
ds.drop(graph, evt, null, gs, gs);
}
} oldMouseUp.apply(this, arguments);
first = null;
};
}; /**
* Creates a drop handler for inserting the given cells.
*/
Sidebar.prototype.createVertexTemplate = function(style, width, height, value)
{
var cells = [new mxCell((value != null) ? value : '', new mxGeometry(0, 0, width, height), style)];
cells[0].vertex = true; return this.createVertexTemplateFromCells(cells, width, height);
}; /**
* Creates a drop handler for inserting the given cells.
*/
Sidebar.prototype.createVertexTemplateFromCells = function(cells, width, height)
{
var elt = this.createItem(cells);
var ds = this.createDragSource(elt, this.createDropHandler(cells, true), this.createDragPreview(width, height));
this.addClickHandler(elt, ds); // Uses guides for vertices only if enabled in graph
ds.isGuidesEnabled = mxUtils.bind(this, function()
{
return this.editorUi.editor.graph.graphHandler.guidesEnabled;
}); // Shows a tooltip with the rendered cell
if (!touchStyle)
{
mxEvent.addListener(elt, 'mousemove', mxUtils.bind(this, function(evt)
{
this.showTooltip(elt, cells);
}));
} return elt;
}; /**
* Creates a drop handler for inserting the given cells.
*/
Sidebar.prototype.createEdgeTemplate = function(style, width, height, value)
{
var cells = [new mxCell((value != null) ? value : '', new mxGeometry(0, 0, width, height), style)];
cells[0].geometry.setTerminalPoint(new mxPoint(0, height), true);
cells[0].geometry.setTerminalPoint(new mxPoint(width, 0), false);
cells[0].edge = true; return this.createEdgeTemplateFromCells(cells, width, height);
}; /**
* Creates a drop handler for inserting the given cells.
*/
Sidebar.prototype.createEdgeTemplateFromCells = function(cells, width, height)
{
var elt = this.createItem(cells);
this.createDragSource(elt, this.createDropHandler(cells, false), this.createDragPreview(width, height)); // Installs the default edge
var graph = this.editorUi.editor.graph;
mxEvent.addListener(elt, 'click', mxUtils.bind(this, function(evt)
{
if (this.installEdges)
{
// Uses edge template for connect preview
graph.connectionHandler.createEdgeState = function(me)
{
return graph.view.createState(cells[0]);
}; // Creates new connections from edge template
graph.connectionHandler.factoryMethod = function()
{
return graph.cloneCells([cells[0]])[0];
};
} // Highlights the entry for 200ms
elt.style.backgroundColor = '#ffffff'; window.setTimeout(function()
{
elt.style.backgroundColor = '';
}, 200); mxEvent.consume(evt);
})); // Shows a tooltip with the rendered cell
if (!touchStyle)
{
mxEvent.addListener(elt, 'mousemove', mxUtils.bind(this, function(evt)
{
this.showTooltip(elt, cells);
}));
} return elt;
}; /**
* Adds the given palette.
*/
Sidebar.prototype.addPalette = function(id, title, expanded, onInit)
{
var elt = this.createTitle(title);
this.container.appendChild(elt); var div = document.createElement('div');
div.className = 'geSidebar'; if (expanded)
{
onInit(div);
onInit = null;
}
else
{
div.style.display = 'none';
} this.addFoldingHandler(elt, div, onInit); var outer = document.createElement('div');
outer.appendChild(div);
this.container.appendChild(outer); // Keeps references to the DOM nodes
if (id != null)
{
this.palettes[id] = [elt, outer];
}
}; /**
* Create the given title element.
*/
Sidebar.prototype.addFoldingHandler = function(title, content, funct)
{
var initialized = false; title.style.backgroundImage = (content.style.display == 'none') ?
'url(' + IMAGE_PATH + '/collapsed.gif)' : 'url(' + IMAGE_PATH + '/expanded.gif)';
title.style.backgroundRepeat = 'no-repeat';
title.style.backgroundPosition = '100% 50%'; mxEvent.addListener(title, 'click', function(evt)
{
if (content.style.display == 'none')
{
if (!initialized)
{
initialized = true; if (funct != null)
{
funct(content);
}
} title.style.backgroundImage = 'url(' + IMAGE_PATH + '/expanded.gif)';
content.style.display = 'block';
}
else
{
title.style.backgroundImage = 'url(' + IMAGE_PATH + '/collapsed.gif)';
content.style.display = 'none';
} mxEvent.consume(evt);
});
}; /**
* Removes the palette for the given ID.
*/
Sidebar.prototype.removePalette = function(id)
{
var elts = this.palettes[id]; if (elts != null)
{
this.palettes[id] = null; for (var i = 0; i < elts.length; i++)
{
this.container.removeChild(elts[i]);
} return true;
} return false;
}; /**
* Adds the given image palette.
*/
Sidebar.prototype.addImagePalette = function(id, title, prefix, postfix, items)
{
this.addPalette(id, title, true, mxUtils.bind(this, function(content)
{
for (var i = 0; i < items.length; i++)
{
var icon = prefix + items[i] + postfix;
content.appendChild(this.createVertexTemplate('image;image=' + icon, 80, 80, ''));
}
}));
}; /**
* Adds the given stencil palette.
*/
Sidebar.prototype.addStencilPalette = function(id, title, stencilFile, style, ignore, onInit, scale)
{
scale = (scale != null) ? scale : 1; this.addPalette(id, title, false, mxUtils.bind(this, function(content)
{
if (style == null)
{
style = '';
} if (onInit != null)
{
onInit.call(this, content);
} mxStencilRegistry.loadStencilSet(stencilFile, mxUtils.bind(this, function(packageName, stencilName, displayName, w, h)
{
if (ignore == null || mxUtils.indexOf(ignore, stencilName) < 0)
{
content.appendChild(this.createVertexTemplate('shape=' + packageName + stencilName.toLowerCase() + style,
Math.round(w * scale), Math.round(h * scale), ''));
}
}), true);
}));
};

对应于配置属性文件的参数变量:

右键菜单绑定设备,设置线宽

文档比较乱! 也有点赶~

欢迎加入一起讨论,后期的开发与研讨,还有一些瓶颈没有解决....

Demo下载地址:点击下载

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须且在文章页面明显位置给出原文链接Dana、Li(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请留言或加Q群!

基于Web实现网络拓扑图的更多相关文章

  1. 基于HTML5的网络拓扑图(1)

    什么是网络拓扑 网络拓扑,指构成网络的成员间特定的排列方式.分为物理的,即真实的.或者逻辑的,即虚拟的两种.如果两个网络的连接结构相同,我们就説它们的网络拓扑相同,尽管它们各自内部的物理接线.节点间距 ...

  2. ECharts整合HT for Web的网络拓扑图应用

    ECharts图形组件在1.0发布的时候我就已经有所关注,今天在做项目的时候遇到了图标的需求,在HT for Web上也有图形组件的功能,但是在尝试了下具体实现后,发现HT for Web的图形组件是 ...

  3. 搭建一个简单的基于web的网络流量监控可视化系统

    本文转载于我的个人博客,转载请标明出处. 初衷 在腾讯云的学生认证申请提交上去n天之后,终于得到了审批,所以迫不及待的想玩玩腾讯云,作为一个搞网络的,自然有一些关于网络应用的小玩意,所以把以前部署过的 ...

  4. ECharts整合HT&#160;for&#160;Web的网络拓扑图应用

    ECharts图形组件在1.0公布的时候我就已经有所关注.今天在做项目的时候遇到了图标的需求,在HTfor Web上也有图形组件的功能.可是在尝试了下详细实现后,发现HT for Web的图形组件是以 ...

  5. 基于Web的网络商城项目设计与实现【SSM+Bootstrap+Vue】

    [Spring+SpringMVC+MyBatis+Bootstrap+Vue] 演示:线路1  线路2 1.系统功能介绍 网上商城系统 是一个功能完善的在线购物系统 - ,主要为在线销售和在线购物服 ...

  6. 基于HTML5的网络拓扑图

    电信网管系统中,设备状态信息的实时展示非常重要,通常会挂载一堆图标来展示状态或告警信息,图标的信息量有限,有时需要更详细的面板,甚至以图表的形式展现,本文将结合最近客户提到的需求,使用 Qunee1. ...

  7. 百度地图、ECharts整合HT for Web网络拓扑图应用

    前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质量的相关报表应用,就想将百度地图.ECharts和HT for Web三者结合起来 ...

  8. ECharts+BaiduMap+HT for Web网络拓扑图应用

    前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质量的相关报表应用,就想将百度地图.ECharts和HT for Web三者结合起来 ...

  9. 快速开发基于 HTML5 网络拓扑图应用

    采用 HT 开发网络拓扑图非常容易,例如<入门手册>的第一个小例子麻雀虽小五脏俱全:http://www.hightopo.com/guide/guide/core/beginners/e ...

随机推荐

  1. 打包python为可执行文件时报错R6034解决方案

    R6034 指的是:”An application has made an attempt to load the C runtime library incorrectly. Please cont ...

  2. python操作数据库-安装

    首先是下载软件: 链接:http://pan.baidu.com/s/1nvp1imX 密码:6i0x 之后就是一系列设置. 安装教程:自行百度就行.需要注意的是设置my.ini时,需要加上这些东西( ...

  3. 基于SceneControl的三维GIS开发

    在ArcGIS体系中,三维开发包括两种:基于Scene的三维开发和基于Globe的三维开发. 由上图可以看出,两种开发的接口都很相似,掌握了Scene开发会相对容易的过渡到Globe开发中. 正如上图 ...

  4. JavaLogin小框架制作【精品博客】

    做一个小登录接口方法,让用户传入用户名,密码,就可以知道登录的结果信息,并以接口监听的方式控制. 先看客户端执行效果: 输入正确: 输入错误: 模拟客户端使用登录小框架: package com.de ...

  5. Python学习-34.Python中os模块的一些方法(二)

    stat方法: 用于获取文件信息,例如创建时间.文件大小等. import os filestate=os.stat("e:/temp/test.txt") print(files ...

  6. 谈谈XAML前端开发

    GUI的发展 在图形用户界面的操作系统(Windows,MAC)出现之前,计算机软件是命令行界面的程序,用户和程序的交互是通过输入命令,查看命令运行结果进行的.当然很不友好.后来出现了文本图形界面的程 ...

  7. Configure Pi as simulation hardware for Simulink

    1. Only version not older than R2013 supports Raspberry Pi. First, download support package in Matla ...

  8. 权限管理系统系列之WCF通信

    目录 权限管理系统系列之序言  首先说下题外话,有些园友看了前一篇[权限管理系统系列之序言]博客加了QQ群(186841119),看了我写的权限管理系统的相关文档(主要是介绍已经开发的功能),给出了一 ...

  9. Android 实现界面(Activity)的跳转

    界面跳转 如,我想重一个界面A跳转到界面B,可以用,setContentView(R.layout.activity_login); 但是他其实只是将改界面铺在了最顶层,而按menu这些菜单其实还是底 ...

  10. Unity Shader序列帧动画学习笔记

    Unity Shader序列帧动画学习笔记 关于无限播放序列帧动画的一点问题 在学shader的序列帧动画时,书上写了这样一段代码: fixed4 frag(v2f i){ // 获得整数时间 flo ...