基于Web实现在线绘画拓扑图[GraphEditor]

网络拓扑图本来已经整理有一段时间了,一次项目会议写集中边界监控系统的时候上级要求使用可以在系统中画网络拓扑图,没办法当时找不到现有的程序来参考
只能硬着头皮,顶着风险来完成[当然来边界安全的,当然要安全型高啊],一同事找到一些源码来分析,当然了有源码分析比自己想的效率要快得多
但是也很让人头痛,怎样才能实现,怎样才能嵌入到Web项目中?
这个集控那个项目已近完成有一段时间了,最近呢一些网友要借鉴我修改后的代码,和一些效果我最近整理了一份但是当时由于比较忙,没有发到博客中
去!只是写了一个简单的Demo供参考和利用,由于最近又有一些朋友也来问这个问题,为了方便与资源共享,我还是整理了这边文章,和网络拓扑的运用,当然
技术肯定还有更加优化好的控件,有的话希望共同学习!
下面是我编写的一个简单的Demo

这是简单画的一个拓扑图:


 

这是简单的绘画界面,Tab切换后是快捷键保存的后的模板[类似图表,也可以编辑],在这里就先不演示了

当然如果需要,请加入群直接下载分享文件[完整的Demo]

下面来详解下文件的配置,和代码分析

首先来看下web.xml



  1.   
  2.   
  3.     This is the description of my J2EE component
  4.     This is the display name of my J2EE component
  5.     SaveToXmlServlet
  6.     grapheditor.SaveToXmlServlet
  7.   
  8.   
  9.     SaveToXmlServlet
  10.     /SaveToXmlServlet
  11.   
  12.   <**-file-list>
  13.     <**-file>graph.jsp
  14.   
复制代码


配置不多,相信熟练Web的开发的这个就不用解释了,一看便能理解其中的配置,这里就不详细介绍了

接着我们来编写JSP页面,这里为了方便看和传输数据,我JS接直接放到一起了


  1. <%@ page language="java" %>
  2. <%@ page contentType="text/html; charset=utf-8"%>
  3. <%String path =request.getContextPath();%>


  4.     Graph Editor
  5.    
  6.    
  7.    
  8.    
  9.    
  10.    
  11.    
  12.    
  13.    
  14.    
  15.    
  16.    
  17.    
  18.    
  19.    
  20.    


  21.    
  22.    
  23.    
复制代码


上诉文件呢,主要负责拓扑图的绘画与相关操作界面的代码

由于相关的文件过多,我这里之举出比较重要的几个问文件

Actions.js主要获取坐标并进行处理的JS文件


  1. function Actions(editorUi)
  2. {
  3.     this.editorUi = editorUi;
  4.     this.actions = new Object();
  5.     this.init();
  6. };

  7. /**
  8. * 添加默认的行为
  9. */
  10. Actions.prototype.init = function()
  11. {
  12.     var ui = this.editorUi;
  13.     var editor = ui.editor;
  14.     var graph = editor.graph;
  15.     graph.cellsMovable=!0;//设置不可移动
  16.     graph.cellsDisconnectable=!0;//设置边不可编辑
  17.     graph.cellsResizable=!0;//设置不可改变大小
  18.     $.post($("#path").val()+"/SaveToXmlServlet",{"tp":$("#mapTp").val(),"type":"get"},function(text){
  19.         if(text=="0"){
  20.             alert("文件加载失败!");
  21.         }else{
  22.             var xml = text;
  23.             var doc = mxUtils.par**ml(xml);
  24.             var model = new mxGraphModel();
  25.             var codec = new mxCodec(doc);
  26.             codec.decode(doc.documentElement, model);
  27.             var children = model.getChildren(model.getChildAt(model.getRoot(), 0));
  28.             graph.setSelectionCells(editor.graph.importCells(children));
  29.         }        
  30.     });
  31.     
  32.     // 文件操作
  33.     this.addAction('new', function() { window.open(ui.getUrl()); });
  34.     this.addAction('open', function()
  35.     {
  36.         window.openNew = true;
  37.         window.openKey = 'open';
  38.         
  39.         ui.openFile();
  40.     });
  41.     this.addAction('import', function()
  42.     {
  43.         window.openNew = false;
  44.         window.openKey = 'import';
  45.         
  46.         // 后关闭对话框打开
  47.         window.openFile = new OpenFile(mxUtils.bind(this, function()
  48.         {
  49.             ui.hideDialog();
  50.         }));
  51.         
  52.         window.openFile.setConsumer(mxUtils.bind(this, function(xml, filename)
  53.         {
  54.             try
  55.             {
  56.                 var doc = mxUtils.par**ml(xml);
  57.                 var model = new mxGraphModel();
  58.                 var codec = new mxCodec(doc);
  59.                 codec.decode(doc.documentElement, model);
  60.                 
  61.                 var children = model.getChildren(model.getChildAt(model.getRoot(), 0));
  62.                 editor.graph.setSelectionCells(editor.graph.importCells(children));
  63.             }
  64.             catch (e)
  65.             {
  66.                 mxUtils.alert(mxResources.get('invalidOrMissingFile') + ': ' + e.message);
  67.             }
  68.         }));

  69.         // 删除openFile是否关闭对话框
  70.         ui.showDialog(new OpenDialog(this).container, 300, 180, true, true, function()
  71.         {
  72.             window.openFile = null;
  73.         });
  74.     });
  75.     this.addAction('save', function() { ui.save(); }, null, null, 'Ctrl+S');
  76.     //addAction(saveAs,函数(){ ui.saveFile(真正);},空,空,“Ctrl + Shift-S”);
  77.     //addAction(“出口”,函数(){ ui。showDialog(新ExportDialog(ui)。容器、300、200,真的,真的);},空,空,“Ctrl + E”);
  78.     //(“editFile”,新的行动(mxResources.get(“编辑”),mxUtils。绑定(此功能()
  79.     //(“editFile”,新的行动(mxResources.get(“编辑”),mxUtils。绑定(此功能()
  80.     this.addAction('pageSetup', function() { ui.showDialog(new PageSetupDialog(ui).container, 300, 200, true, true); });
  81.     this.addAction('print', function() { ui.showDialog(new PrintDialog(ui).container, 300, 200, true, true); }, null, 'sprite-print', 'Ctrl+P');
  82.     this.addAction('preview', function() { mxUtils.show(graph, null, 10, 10); });
  83.     
  84.     // Edit actions
  85.     this.addAction('undo', function() { editor.undoManager.undo(); }, null, 'sprite-undo', 'Ctrl+Z');
  86.     this.addAction('redo', function() { editor.undoManager.redo(); }, null, 'sprite-redo', 'Ctrl+Y');
  87.     this.addAction('cut', function() { mxClipboard.cut(graph); }, null, 'sprite-cut', 'Ctrl+X');
  88.     this.addAction('copy', function() { mxClipboard.copy(graph); }, null, 'sprite-copy', 'Ctrl+C');
  89.     this.addAction('paste', function() { mxClipboard.paste(graph); }, false, 'sprite-paste', 'Ctrl+V');
  90.     this.addAction('delete', function() { graph.removeCells(); }, null, null, 'Delete');
  91.     this.addAction('duplicate', function()
  92.     {
  93.         var s = graph.gridSize;
  94.         graph.setSelectionCells(graph.moveCells(graph.getSelectionCells(), s, s, true));
  95.     }, null, null, 'Ctrl+D');
  96.     this.addAction('selectVertices', function() { graph.selectVertices(); }, null, null, 'Ctrl+Shift+V');
  97.     this.addAction('selectEdges', function() { graph.selectEdges(); }, null, null, 'Ctrl+Shift+E');
  98.     this.addAction('selectAll', function() { graph.selectAll(); }, null, null, 'Ctrl+A');

  99.     // 导航
  100.     this.addAction('home', function() { graph.home(); }, null, null, 'Home');
  101.     this.addAction('exitGroup', function() { graph.exitGroup(); }, null, null, 'Page Up');
  102.     this.addAction('enterGroup', function() { graph.enterGroup(); }, null, null, 'Page Down');
  103.     this.addAction('expand', function() { graph.foldCells(false); }, null, null, 'Enter');
  104.     this.addAction('collapse', function() { graph.foldCells(true); }, null, null, 'Backspace');

  105.     //安排操作
  106.     this.addAction('toFront', function() { graph.orderCells(false); }, null, null, 'Ctrl+F');
  107.     this.addAction('toBack', function() { graph.orderCells(true); }, null, null, 'Ctrl+B');
  108.     this.addAction('group', function() { graph.setSelectionCell(graph.groupCells(null, 0)); }, null, null, 'Ctrl+G');
  109.     this.addAction('ungroup', function() { graph.setSelectionCells(graph.ungroupCells()); }, null, null, 'Ctrl+U');
  110.     this.addAction('removeFromGroup', function() { graph.removeCellsFromParent(); });
  111.     this.addAction('editLink', function()
  112.     {
  113.         var cell = graph.getSelectionCell();
  114.         var link = graph.getLinkForCell(cell);
  115.         
  116.         if (link == null)
  117.         {
  118.             link = '';
  119.         }
  120.         
  121.         link = mxUtils.prompt(mxResources.get('enterValue'), link);
  122.         
  123.         if (link != null)
  124.         {
  125.             graph.setLinkForCell(cell, link);
  126.         }
  127.     });
  128.     this.addAction('openLink', function()
  129.     {
  130.         var cell = graph.getSelectionCell();
  131.         var link = graph.getLinkForCell(cell);
  132.         
  133.         if (link != null)
  134.         {
  135.             window.open(link);
  136.         }
  137.     });
  138.     this.addAction('autosize', function()
  139.     {
  140.         var cells = graph.getSelectionCells();
  141.         
  142.         if (cells != null)
  143.         {
  144.             graph.getModel().beginUpdate();
  145.             try
  146.             {
  147.                 for (var i = 0; i < cells.length; i++)
  148.                 {
  149.                     var cell = cells[i];
  150.                     
  151.                     if (graph.getModel().getChildCount(cell))
  152.                     {
  153.                         graph.updateGroupBounds([cell], 20);
  154.                     }
  155.                     else
  156.                     {
  157.                         graph.updateCellSize(cell);
  158.                     }
  159.                 }
  160.             }
  161.             finally
  162.             {
  163.                 graph.getModel().endUpdate();
  164.             }
  165.         }
  166.     });
  167.     this.addAction('rotation', function()
  168.     {
  169.         var value = '0';
  170.         var state = graph.getView().getState(graph.getSelectionCell());
  171.         
  172.         if (state != null)
  173.         {
  174.             value = state.style[mxConstants.STYLE_ROTATION] || value;
  175.         }

  176.         value = mxUtils.prompt(mxResources.get('enterValue') + ' (' +
  177.                 mxResources.get('rotation') + ' 0-360)', value);
  178.             
  179.         if (value != null)
  180.         {
  181.             graph.setCellStyles(mxConstants.STYLE_ROTATION, value);
  182.         }
  183.     });
  184.     this.addAction('rotate', function()
  185.     {
  186.         var cells = graph.getSelectionCells();
  187.         
  188.         if (cells != null)
  189.         {
  190.             graph.getModel().beginUpdate();
  191.             try
  192.             {
  193.                 for (var i = 0; i < cells.length; i++)
  194.                 {
  195.                     var cell = cells[i];
  196.                     
  197.                     if (graph.getModel().isVertex(cell) && graph.getModel().getChildCount(cell) == 0)
  198.                     {
  199.                         var geo = graph.getCellGeometry(cell);
  200.             
  201.                         if (geo != null)
  202.                         {
  203.                             // 旋转几何图形的大小和位置
  204.                             geo = geo.clone();
  205.                             geo.x += geo.width / 2 - geo.height / 2;
  206.                             geo.y += geo.height / 2 - geo.width / 2;
  207.                             var tmp = geo.width;
  208.                             geo.width = geo.height;
  209.                             geo.height = tmp;
  210.                             graph.getModel().setGeometry(cell, geo);
  211.                             
  212.                             //读取当前的方向并提出90度
  213.                             var state = graph.view.getState(cell);
  214.                             
  215.                             if (state != null)
  216.                             {
  217.                                 var dir = state.style[mxConstants.STYLE_DIRECTION] || 'east'/*default*/;
  218.                                 
  219.                                 if (dir == 'east')
  220.                                 {
  221.                                     dir = 'south';
  222.                                 }
  223.                                 else if (dir == 'south')
  224.                                 {
  225.                                     dir = 'west';
  226.                                 }
  227.                                 else if (dir == 'west')
  228.                                 {
  229.                                     dir = 'north';
  230.                                 }
  231.                                 else if (dir == 'north')
  232.                                 {
  233.                                     dir = 'east';
  234.                                 }
  235.                                 
  236.                                 graph.setCellStyles(mxConstants.STYLE_DIRECTION, dir, [cell]);
  237.                             }
  238.                         }
  239.                     }
  240.                 }
  241.             }
  242.             finally
  243.             {
  244.                 graph.getModel().endUpdate();
  245.             }
  246.         }
  247.     }, null, null, 'Ctrl+R');
  248.     
  249.     //视图操作
  250.     this.addAction('actualSize', function()
  251.     {
  252.         graph.zoomTo(1);
  253.     });
  254.     this.addAction('zoomIn', function() { graph.zoomIn(); }, null, null, 'Add');
  255.     this.addAction('zoomOut', function() { graph.zoomOut(); }, null, null, 'Subtract');
  256.     this.addAction('fitWindow', function() { graph.fit(); });

  257.     this.addAction('fitPage', mxUtils.bind(this, function()
  258.     {
  259.         if (!graph.pageVisible)
  260.         {
  261.             this.get('pageView').funct();
  262.         }
  263.         var fmt = graph.pageFormat;
  264.         var ps = graph.pageScale;
  265.         var cw = graph.container.clientWidth - 20;
  266.         var ch = graph.container.clientHeight - 20;
  267.         
  268.         var scale = Math.floor(100 * Math.min(cw / fmt.width / ps, ch / fmt.height / ps)) / 100;
  269.         graph.zoomTo(scale);
  270.         
  271.         graph.container.scrollLeft = Math.round(graph.view.translate.x * scale - Math.max(10, (graph.container.clientWidth - fmt.width * ps * scale) / 2));
  272.         graph.container.scrollTop = Math.round(graph.view.translate.y * scale - Math.max(10, (graph.container.clientHeight - fmt.height * ps * scale) / 2));
  273.     }));
  274.     this.addAction('fitPageWidth', mxUtils.bind(this, function()
  275.     {
  276.         if (!graph.pageVisible)
  277.         {
  278.             this.get('pageView').funct();
  279.         }
  280.         
  281.         var fmt = graph.pageFormat;
  282.         var ps = graph.pageScale;
  283.         var cw = graph.container.clientWidth - 20;
  284.         
  285.         var scale = Math.floor(100 * cw / fmt.width / ps) / 100;
  286.         graph.zoomTo(scale);
  287.         
  288.         graph.container.scrollLeft = Math.round(graph.view.translate.x * scale - Math.max(10, (graph.container.clientWidth - fmt.width * ps * scale) / 2));
  289.         graph.container.scrollTop = Math.round(graph.view.translate.y * scale - Math.max(10, (graph.container.clientHeight - fmt.height * ps * scale) / 2));
  290.     }));
  291.     this.put('customZoom', new Action(mxResources.get('custom'), function()
  292.     {
  293.         var value = mxUtils.prompt(mxResources.get('enterValue') + ' (%)', parseInt(graph.getView().getScale() * 100));
  294.         
  295.         if (value != null && value.length > 0 && !isNaN(parseInt(value)))
  296.         {
  297.             graph.zoomTo(parseInt(value) / 100);
  298.         }
  299.     }));
  300.     
  301.     //选择操作
  302.     var action = null;
  303.     action = this.addAction('grid', function()
  304.     {
  305.         graph.setGridEnabled(!graph.isGridEnabled());
  306.         editor.updateGraphComponents();
  307.     }, null, null, 'Ctrl+Shift+G');
  308.     action.setToggleAction(true);
  309.     action.setSelectedCallback(function() { return graph.isGridEnabled(); });
  310.     action = this.addAction('guides', function() { graph.graphHandler.guidesEnabled = !graph.graphHandler.guidesEnabled; });
  311.     action.setToggleAction(true);
  312.     action.setSelectedCallback(function() { return graph.graphHandler.guidesEnabled; });
  313.     action = this.addAction('tooltips', function()
  314.     {
  315.         graph.tooltipHandler.setEnabled(!graph.tooltipHandler.isEnabled());
  316.     });
  317.     action.setToggleAction(true);
  318.     action.setSelectedCallback(function() { return graph.tooltipHandler.isEnabled(); });
  319.     action = this.addAction('navigation', function()
  320.     {
  321.         graph.foldingEnabled = !graph.foldingEnabled;
  322.         graph.view.revalidate();
  323.     });
  324.     action.setToggleAction(true);
  325.     action.setSelectedCallback(function() { return graph.foldingEnabled; });
  326.     action = this.addAction('scrollbars', function()
  327.     {
  328.         graph.scrollbars = !graph.scrollbars;
  329.         editor.updateGraphComponents();

  330.         if (!graph.scrollbars)
  331.         {
  332.             var t = graph.view.translate;
  333.             graph.view.setTranslate(t.x - graph.container.scrollLeft / graph.view.scale, t.y - graph.container.scrollTop / graph.view.scale);
  334.             graph.container.scrollLeft = 0;
  335.             graph.container.scrollTop = 0;
  336.             graph.sizeDidChange();
  337.         }
  338.         else
  339.         {
  340.             var dx = graph.view.translate.x;
  341.             var dy = graph.view.translate.y;

  342.             graph.view.translate.x = 0;
  343.             graph.view.translate.y = 0;
  344.             graph.sizeDidChange();
  345.             graph.container.scrollLeft -= Math.round(dx * graph.view.scale);
  346.             graph.container.scrollTop -= Math.round(dy * graph.view.scale);
  347.         }
  348.     }, !mxClient.IS_TOUCH);
  349.     action.setToggleAction(true);
  350.     action.setSelectedCallback(function() { return graph.container.style.overflow == 'auto'; });
  351.     action = this.addAction('pageView', mxUtils.bind(this, function()
  352.     {
  353.         graph.pageVisible = !graph.pageVisible;
  354.         graph.pageBreaksVisible = graph.pageVisible; 
  355.         graph.preferPageSize = graph.pageBreaksVisible;
  356.         graph.view.validate();
  357.         graph.sizeDidChange();
  358.         
  359.         editor.updateGraphComponents();
  360.         editor.outline.update();
  361.         
  362.         if (mxUtils.hasScrollbars(graph.container))
  363.         {
  364.             if (graph.pageVisible)
  365.             {
  366.                 graph.container.scrollLeft -= 20;
  367.                 graph.container.scrollTop -= 20;
  368.             }
  369.             else
  370.             {
  371.                 graph.container.scrollLeft += 20;
  372.                 graph.container.scrollTop += 20;
  373.             }
  374.         }
  375.     }));
  376.     action.setToggleAction(true);
  377.     action.setSelectedCallback(function() { return graph.pageVisible; });
  378.     this.put('pageBackgroundColor', new Action(mxResources.get('backgroundColor'), function()
  379.     {
  380.         var apply = function(color)
  381.         {
  382.             graph.background = color;
  383.             editor.updateGraphComponents();
  384.         };

  385.         var cd = new ColorDialog(ui, graph.background || 'none', apply);
  386.         ui.showDialog(cd.container, 220, 360, true, false);
  387.         
  388.         if (!mxClient.IS_TOUCH)
  389.         {
  390.             cd.colorInput.focus();
  391.         }
  392.     }));
  393.     action = this.addAction('connect', function()
  394.     {
  395.         graph.setConnectable(!graph.connectionHandler.isEnabled());
  396.     }, null, null, 'Ctrl+Q');
  397.     action.setToggleAction(true);
  398.     action.setSelectedCallback(function() { return graph.connectionHandler.isEnabled(); });
  399.     

  400.     this.addAction('help', function()
  401.     {
  402.         var ext = '';
  403.         
  404.         if (mxResources.isLanguageSupported(mxClient.language))
  405.         {
  406.             ext = '_' + mxClient.language;
  407.         }
  408.         
  409.         window.open(RESOURCES_PATH + '/help' + ext + '.html');
  410.     });
  411.     this.put('about', new Action(mxResources.get('about') + ' Graph Editor', function()
  412.     {
  413.         ui.showDialog(new AboutDialog(ui).container, 320, 280, true, true);
  414.     }, null, null, 'F1'));
  415.     
  416.     //风格
  417.     var toggleFontStyle = mxUtils.bind(this, function(key, style)
  418.     {
  419.         this.addAction(key, function()
  420.         {
  421.             graph.toggleCellStyleFlags(mxConstants.STYLE_FONTSTYLE, style);
  422.         });
  423.     });
  424.     
  425.     toggleFontStyle('bold', mxConstants.FONT_BOLD);
  426.     toggleFontStyle('italic', mxConstants.FONT_ITALIC);
  427.     toggleFontStyle('underline', mxConstants.FONT_UNDERLINE);
  428.     
  429.     //颜色
  430.     this.addAction('fontColor', function() { ui.menus.pickColor(mxConstants.STYLE_FONTCOLOR); });
  431.     this.addAction('strokeColor', function() { ui.menus.pickColor(mxConstants.STYLE_STROKECOLOR); });
  432.     this.addAction('fillColor', function() { ui.menus.pickColor(mxConstants.STYLE_FILLCOLOR); });
  433.     this.addAction('gradientColor', function() { ui.menus.pickColor(mxConstants.STYLE_GRADIENTCOLOR); });
  434.     this.addAction('backgroundColor', function() { ui.menus.pickColor(mxConstants.STYLE_LABEL_BACKGROUNDCOLOR); });
  435.     this.addAction('borderColor', function() { ui.menus.pickColor(mxConstants.STYLE_LABEL_BORDERCOLOR); });
  436.     
  437.     // 格式
  438.     this.addAction('shadow', function() { graph.toggleCellStyles(mxConstants.STYLE_SHADOW); });
  439.     this.addAction('dashed', function() { graph.toggleCellStyles(mxConstants.STYLE_DASHED); });
  440.     this.addAction('rounded', function() { graph.toggleCellStyles(mxConstants.STYLE_ROUNDED); });
  441.     this.addAction('style', function()
  442.     {
  443.         var cells = graph.getSelectionCells();
  444.         
  445.         if (cells != null && cells.length > 0)
  446.         {
  447.             var model = graph.getModel();
  448.             var style = mxUtils.prompt(mxResources.get('enterValue')+ ' (' + mxResources.get('style') + ')',
  449.                     model.getStyle(cells[0]) || '');

  450.             if (style != null)
  451.             {
  452.                 graph.setCellStyle(style, cells);
  453.             }
  454.         }
  455.     });
  456.     this.addAction('setAsDefaultEdge', function()
  457.     {
  458.         var cell = graph.getSelectionCell();
  459.         
  460.         if (cell != null && graph.getModel().isEdge(cell))
  461.         {
  462.             //目前采取的快照单元的调用
  463.             var proto = graph.getModel().cloneCells([cell])[0];
  464.             
  465.             //删除条目- / exitXY风格
  466.             var style = proto.getStyle();
  467.             style = mxUtils.setStyle(style, mxConstants.STYLE_ENTRY_X, '');
  468.             style = mxUtils.setStyle(style, mxConstants.STYLE_ENTRY_Y, '');
  469.             style = mxUtils.setStyle(style, mxConstants.STYLE_EXIT_X, '');
  470.             style = mxUtils.setStyle(style, mxConstants.STYLE_EXIT_Y, '');
  471.             proto.setStyle(style);
  472.             
  473.             //使用连接的边缘模板预览
  474.             graph.connectionHandler.createEdgeState = function(me)
  475.             {
  476.                 return graph.view.createState(proto);
  477.             };
  478.     
  479.             //从边缘模板创建新连接
  480.             graph.connectionHandler.factoryMethod = function()
  481.             {
  482.                 return graph.cloneCells([proto])[0];
  483.             };
  484.         }
  485.     });
  486.     this.addAction('image', function()
  487.     {
  488.         function updateImage(value, w, h)
  489.         {
  490.             var select = null;
  491.             var cells = graph.getSelectionCells();
  492.             
  493.             graph.getModel().beginUpdate();
  494.             try
  495.             {
  496.                 //如果没有选中单元格插入新的细胞
  497.                 if (cells.length == 0)
  498.                 {
  499.                     var gs = graph.getGridSize();
  500.                     cells = [graph.insertVertex(graph.getDefaultParent(), null, '', gs, gs, w, h)];
  501.                     select = cells;
  502.                 }
  503.                 
  504.                 graph.setCellStyles(mxConstants.STYLE_IMAGE, value, cells);
  505.                 graph.setCellStyles(mxConstants.STYLE_SHAPE, 'image', cells);
  506.                 
  507.                 if (graph.getSelectionCount() == 1)
  508.                 {
  509.                     if (w != null && h != null)
  510.                     {
  511.                         var cell = cells[0];
  512.                         var geo = graph.getModel().getGeometry(cell);
  513.                         
  514.                         if (geo != null)
  515.                         {
  516.                             geo = geo.clone();
  517.                             geo.width = w;
  518.                             geo.height = h;
  519.                             graph.getModel().setGeometry(cell, geo);
  520.                         }
  521.                     }
  522.                 }
  523.             }
  524.             finally
  525.             {
  526.                 graph.getModel().endUpdate();
  527.             }
  528.             
  529.             if (select != null)
  530.             {
  531.                 graph.setSelectionCells(select);
  532.                 graph.scrollCellToVisible(select[0]);
  533.             }
  534.         };

  535.         var value = '';
  536.         var state = graph.getView().getState(graph.getSelectionCell());
  537.         
  538.         if (state != null)
  539.         {
  540.             value = state.style[mxConstants.STYLE_IMAGE] || value;
  541.         }

  542.         value = mxUtils.prompt(mxResources.get('enterValue') + ' (' + mxResources.get('url') + ')', value);

  543.         if (value != null)
  544.         {
  545.             if (value.length > 0)
  546.             {
  547.                 var img = new Image();
  548.                 
  549.                 img.onload = function()
  550.                 {
  551.                     updateImage(value, img.width, img.height);
  552.                 };
  553.                 img.onerror = function()
  554.                 {
  555.                     mxUtils.alert(mxResources.get('fileNotFound'));
  556.                 };
  557.                 
  558.                 img.src = value;
  559.             }
  560.         }
  561.     });
  562. };

  563. /**
  564. * 注册名字下行动。
  565. */
  566. Actions.prototype.addAction = function(key, funct, enabled, iconCls, shortcut)
  567. {
  568.     return this.put(key, new Action(mxResources.get(key), funct, enabled, iconCls, shortcut));
  569. };

  570. /**
  571. *注册名字下行动。
  572. */
  573. Actions.prototype.put = function(name, action)
  574. {
  575.     this.actions[name] = action;
  576.     
  577.     return action;
  578. };

  579. /**
  580. * 返回给定名称的行动或null如果没有这样的行动存在。
  581. */
  582. Actions.prototype.get = function(name)
  583. {
  584.     return this.actions[name];
  585. };

  586. /**
  587. * 构造一个新的行动为给定的参数。
  588. */
  589. function Action(label, funct, enabled, iconCls, shortcut)
  590. {
  591.     mxEventSource.call(this);
  592.     this.label = label;
  593.     this.funct = funct;
  594.     this.enabled = (enabled != null) ? enabled : true;
  595.     this.iconCls = iconCls;
  596.     this.shortcut = shortcut;
  597. };

  598. //行动继承自mxEventSource
  599. mxUtils.extend(Action, mxEventSource);

  600. Action.prototype.setEnabled = function(value)
  601. {
  602.     if (this.enabled != value)
  603.     {
  604.         this.enabled = value;
  605.         this.fireEvent(new mxEventObject('stateChanged'));
  606.     }
  607. };

  608. Action.prototype.setToggleAction = function(value)
  609. {
  610.     this.toggleAction = value;
  611. };

  612. Action.prototype.setSelectedCallback = function(funct)
  613. {
  614.     this.selectedCallback = funct;
  615. };

  616. Action.prototype.isSelected = function()
  617. {
  618.     return this.selectedCallback();
  619. };
复制代码


进行坐标分配的XML文件集以及相应的图标

 

以一个数据库图标的坐标管理XML的部分数据为例database.xml




























复制代码


我写的这个SaveToXmlServlet.java文件的目的是将网络拓扑图保存至对应的XML文件中  以及  读取网络拓扑图对应的XML文件

  1. package grapheditor;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileReader;
  5. import java.io.IOException;
  6. import java.io.PrintWriter;
  7. import java.io.RandomAccessFile;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.http.HttpServlet;
  10. import javax.servlet.http.HttpServletRequest;
  11. import javax.servlet.http.HttpServletResponse;
  12. /**
  13. * 将网络拓扑图保存至对应的XML文件中  以及  读取网络拓扑图对应的XML文件
  14. * @author Visec·Dana
  15. * @version V2.0  2014-7-17
  16. */
  17. public class SaveToXmlServlet extends HttpServlet {
  18.     private static final long serialVersionUID = 1L;
  19.     public void doGet(HttpServletRequest request, HttpServletResponse response)
  20.             throws ServletException, IOException {
  21.         this.doPost(request, response);
  22.     }
  23.     public void doPost(HttpServletRequest request, HttpServletResponse response)
  24.             throws ServletException, IOException {
  25.         response.setContentType("text/html;charset=utf-8");
  26.         response.setCharacterEncoding("utf-8");
  27.         request.setCharacterEncoding("utf-8");
  28.         String type = request.getParameter("type");
  29.         String tp = request.getParameter("tp");
  30.         StringBuffer result = new StringBuffer("");
  31.         String xmlPath=new String("");
  32.         String strPath = this.getClass().getResource("/").toString();
  33.         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";
  34.         String osName = System.getProperties().getProperty("os.name");
  35.         if(osName.toLowerCase().indexOf("windows")>-1){
  36.             strPath=strPath.substring(6)+xmlPath;
  37.         }else{
  38.             strPath=strPath.substring(5)+xmlPath;
  39.         }
  40.         File file = new File(strPath);
  41.         if(file.isFile()){//判断该路径是否为一个文件
  42.             if("set".equals(type.toLowerCase())){//文件保存
  43.                 String xml = request.getParameter("xml");
  44.                 if(xml==null||"".equals(xml)){
  45.                     result.append("0");
  46.                 }else{
  47.                     RandomAccessFile randomAccessFile = new RandomAccessFile(strPath, "rw");
  48.                     randomAccessFile.seek(0);
  49.                     randomAccessFile.setLength(0);
  50.                     randomAccessFile.write(xml.getBytes());
  51.                     randomAccessFile.close();
  52.                     result.append("1");
  53.                 }
  54.             }else if("get".equals(type.toLowerCase())){//获取文件信息
  55.                 //开始读取
  56.                 BufferedReader reader = new BufferedReader(new FileReader(new File(strPath)));
  57.                 String tempString = null;
  58.                 // 一次读入一行,直到读入null为文件结束
  59.                 while ((tempString = reader.readLine()) != null){
  60.                     result.append(tempString);
  61.                 }
  62.                 reader.close();
  63.             }
  64.         }else{
  65.             System.out.println(strPath+"  找不到!");
  66.             result.append("0");
  67.         }

  68.         PrintWriter out = response.getWriter();
  69.         out.write(result.toString());
  70.         out.flush();
  71.         out.close();
  72.     }

  73. }
复制代码


当然这个文件的基础是先前有绘制好的拓扑图已经保存了相应的坐标位置和相应的数据

 

我编写network_qsy.xml是用来存储相应的坐标的临时文件

文件配置,以及不同项目之间的嵌入都不一样,所有就不详细介绍了,如感兴趣的朋友欢加入群一起探讨更多相关技术提高自身水平!

当然部分网友可能留意到

 


这里部分功能是没有完善的,能力有限,还需一些时间来琢磨!

当然后期的开发是无穷的,后期也在此基础上添加了右键绑定相关设备,合一拖动的形式配置相关信息,


 


参考资料:http://www.yworks.com/en/products_yed_about.html


              http://docs.cryengine.com/display/SDKDOC2/Flow+Graph+Editor


              http://www.univ-orleans.fr/lifo/ ... ns/GraphEditor.html


上诉网站都是英文版的当时,也只是略看一些资料!


via:http://www.cnblogs.com/visec479/p/3965795.html

你可能感兴趣的:(前端,javascript)