日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mxgraph初体验

發布時間:2024/1/8 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mxgraph初体验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近公司讓學習了mxgraph,簡單總結一下

(1)mxGraph學習路徑

  1)API:http://jgraph.github.io/mxgraph/docs/js-api/files/index-txt.html

  2)demo:http://jgraph.github.io/mxgraph/javascript/index.html

(2)最簡單的例子(helloword)

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Hello World</title><style>html, body {height: 100%;}#graphContainer {position: relative;overflow: hidden;width: 100%;height: 100%;background: url('./images/grid.gif');cursor: default;}</style> </head><body onload="main(document.getElementById('graphContainer'))"> <div id="graphContainer"></div> </body><script> const mxBasePath = '../static/mxgraph'; </script><script src="../mxClient.js"></script> <script> function main(container) {// 禁用鼠標右鍵 mxEvent.disableContextMenu(container);const graph = new mxGraph(container);// 設置這個屬性后節點之間才可以連接 graph.setConnectable(true);// 開啟區域選擇new mxRubberband(graph);const parent = graph.getDefaultParent();graph.getModel().beginUpdate();try {const v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);//創建第一個節點 const v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);//創建第二個節點 const e1 = graph.insertEdge(parent, null, '30%', v1, v2);//創建連線 } finally {graph.getModel().endUpdate();} } </script> </html>

?圖:

(3)mxGraph將圖轉換成xml字符串

var graph = new mxGraph(container); var xml = mxUtils.getXml(new mxCodec().encode(graph.getModel())) ; console.log(xml)

如下,左圖可得右XML

(4)Java后臺解析xml

package org.sxdata.jingwei.util.transUtil;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID;import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList;/*** @author sonyan* @version 2019年8月14日 下午3:09:15* @desc*/ public class DocumentUtil {private static String xmlStr = "";private static List<Map<String, Object>> nodeMapList = new ArrayList<Map<String, Object>>();/*** 將指定的document解析成xml字符串* @param doc* @return*/public static String getXmlStrByDocument(Document doc) {xmlStr = "";// 根節點名稱String rootName = doc.getDocumentElement().getTagName();// 遞歸解析ElementElement element = doc.getDocumentElement();return getElementStr(element);}/*** 將指定的節點解析成xml字符串* @param element* @return*/public static String getElementStr(Element element) {String TagName = element.getTagName();boolean flag = true;xmlStr = xmlStr + "<" + TagName;NamedNodeMap attris = element.getAttributes();for (int i = 0; i < attris.getLength(); i++) {Attr attr = (Attr) attris.item(i);xmlStr = xmlStr + " " + attr.getName() + "=\"" + attr.getValue() + "\"";}xmlStr = xmlStr + ">" ;NodeList nodeList = element.getChildNodes();Node childNode;for (int temp = 0; temp < nodeList.getLength(); temp++) {childNode = nodeList.item(temp);// 判斷是否屬于節點if (childNode.getNodeType() == Node.ELEMENT_NODE) {// 判斷是否還有子節點 getElementStr((Element) childNode);if (childNode.getNodeType() != Node.COMMENT_NODE) {xmlStr = xmlStr + childNode.getTextContent();}}}xmlStr = xmlStr + "</" + element.getTagName() + ">";return xmlStr;}/*** 解析節點* @param element* @param graphId 所屬圖的id*/public static void parseElement(Element element, String graphId) {NodeList nodeList = element.getChildNodes();Node childNode;for (int temp = 0; temp < nodeList.getLength(); temp++) {childNode = nodeList.item(temp);String id= getUUID32();String nodeId = getNodeAttrValue(childNode, "id");if (!"0".equals(nodeId) && !"1".equals(nodeId) && "mxCell".equals(childNode.getNodeName())) {System.out.println(childNode.getNodeName());System.out.println("graphid:" + graphId);System.out.println("nodeId:" + getNodeAttrValue(childNode, "id"));System.out.println("parent:" + getNodeAttrValue(childNode, "parent"));System.out.println("value:" + getNodeAttrValue(childNode, "value"));System.out.println("source:" + getNodeAttrValue(childNode, "source"));System.out.println("target:" + getNodeAttrValue(childNode, "target"));System.out.println("vertex:" + getNodeAttrValue(childNode, "vertex"));System.out.println("edge:" + getNodeAttrValue(childNode, "edge"));parseElement2((Element) childNode, nodeId,graphId);System.out.println("****end*****");Map<String, Object> node = new HashMap<String, Object>();node.put("id", id);node.put("nodeId", nodeId);node.put("graphId", graphId);node.put("parent", getNodeAttrValue(childNode, "parent"));node.put("nodeValue", getNodeAttrValue(childNode, "value"));node.put("source", getNodeAttrValue(childNode, "source"));node.put("target", getNodeAttrValue(childNode, "target"));node.put("edge", getNodeAttrValue(childNode, "edge"));node.put("vertex", getNodeAttrValue(childNode, "vertex"));node.put("style", getNodeAttrValue(childNode, "style"));node.put("ass", getNodeAttrValue(childNode, "as"));node.put("nodeName", childNode.getNodeName());nodeMapList.add(node);}// 判斷是否屬于節點if (childNode.getNodeType() == Node.ELEMENT_NODE) {// 判斷是否還有子節點 parseElement((Element) childNode, graphId);}}}/*** 解析mxGeometry節點* @param element * @param parentId * @param graphId*/private static void parseElement2(Element element, String parentId, String graphId) {NodeList nodeList = element.getChildNodes();Node childNode;for (int temp = 0; temp < nodeList.getLength(); temp++) {childNode = nodeList.item(temp);String nodeName = childNode.getNodeName();if ("mxGeometry".equals(nodeName)) {String nodeId = getNodeAttrValue(childNode, "id");String id = getUUID32();System.out.println("--name:" + nodeName);System.out.println("--height:" + getNodeAttrValue(childNode, "height"));System.out.println("--width:" + getNodeAttrValue(childNode, "height"));System.out.println("--x:" + getNodeAttrValue(childNode, "x"));System.out.println("--y:" + getNodeAttrValue(childNode, "y"));System.out.println("--as:" + getNodeAttrValue(childNode, "as"));System.out.println("--relative:" + getNodeAttrValue(childNode, "relative"));Map<String, Object> node = new HashMap<String, Object>();node.put("id", id);node.put("nodeId", nodeId);node.put("parent", parentId);node.put("nodeName", childNode.getNodeName());node.put("height", getNodeAttrValue(childNode, "height"));node.put("width", getNodeAttrValue(childNode, "width"));node.put("x", getNodeAttrValue(childNode, "x"));node.put("y", getNodeAttrValue(childNode, "y"));node.put("ass", getNodeAttrValue(childNode, "as"));node.put("relative", getNodeAttrValue(childNode, "relative"));node.put("graphId",graphId);node.put("style", getNodeAttrValue(childNode, "style"));// node.put("value", getNodeAttrValue(childNode, "value"));// node.put("source", getNodeAttrValue(childNode, "source"));// node.put("target", getNodeAttrValue(childNode, "target"));// node.put("edge", getNodeAttrValue(childNode, "edge"));// node.put("vertex", getNodeAttrValue(childNode, "vertex")); nodeMapList.add(node);// 判斷是否屬于節點if (childNode.getNodeType() == Node.ELEMENT_NODE) {// 判斷是否還有子節點parseElement((Element) childNode, "");}}}}/*** 獲取指定節點的指定屬性的值* @param node* @param attrName* @return*/public static String getNodeAttrValue(Node node, String attrName) {NamedNodeMap attr = node.getAttributes();if (attr != null) {Node attrNode = attr.getNamedItem(attrName);if (attrNode != null) {return attrNode.getNodeValue();}}return "";}/*** 獲取指定的document對象中要保存的節點對象* @param doc* @return*/public static List<Map<String, Object>> parseDocument(Document doc) {String id ="6ed10c4036f245b8bf78e1141d85e23b";// doc.getDocumentElement().getAttribute("id");if ("".equals(id)) {id = getUUID32();}// 遞歸解析ElementElement element = doc.getDocumentElement();nodeMapList.clear();parseElement(element, id);return nodeMapList;}/*** 根據圖的id獲取圖的xml字符串* @param graphId* @return*/public static String getXmlByGraphId(String graphId){xmlStr = "";// 根節點名稱/*String rootName = doc.getDocumentElement().getTagName();// 遞歸解析ElementElement element = doc.getDocumentElement();*/return getElementStr(null);}/*** 生成32位主鍵* @return*/public static String getUUID32() {return UUID.randomUUID().toString().replace("-", "").toLowerCase();}public static Document createDocument() {// 初始化xml解析工廠DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 創建DocumentBuilderDocumentBuilder builder = null;try {builder = factory.newDocumentBuilder();} catch (ParserConfigurationException e) {e.printStackTrace();}// 創建DocumentDocument doc = builder.newDocument();// standalone用來表示該文件是否呼叫其它外部的文件。若值是 ”yes” 表示沒有呼叫外部文件doc.setXmlStandalone(true);// 創建一個根節點// 說明:// doc.createElement("元素名")、element.setAttribute("屬性名","屬性值")、element.setTextContent("標簽間內容")Element diagram = doc.createElement("diagram");diagram.setAttribute("id", "");diagram.setAttribute("tcn", "");// 創建根節點第一個子節點Element mxGraphModel = doc.createElement("mxGraphModel");diagram.appendChild(mxGraphModel);Element root = doc.createElement("root");mxGraphModel.appendChild(root);Element mxCell1 = doc.createElement("mxCell");mxCell1.setAttribute("id", "0");root.appendChild(mxCell1);Element mxCell2 = doc.createElement("mxCell");mxCell2.setAttribute("id", "1");mxCell2.setAttribute("parent", "0");root.appendChild(mxCell2);//根據圖的id獲取圖中節點/*Element mxCell3 = doc.createElement("mxCell");mxCell3.setAttribute("id", "2");mxCell3.setAttribute("parent", "1");mxCell3.setAttribute("vertex", "1");mxCell3.setAttribute("value", "songyan");root.appendChild(mxCell3);Element mxGeometry = doc.createElement("mxGeometry");mxGeometry.setAttribute("x", "20");mxGeometry.setAttribute("y", "20");mxGeometry.setAttribute("width", "80");mxGeometry.setAttribute("height", "30");mxGeometry.setAttribute("as", "geometry");mxCell3.appendChild(mxGeometry);*/// 添加根節點 doc.appendChild(diagram);return doc;}/*** 根據圖的id獲取document對象* @param graphId 圖的id* @return*/public static Document getDocumentByGraphId(String graphId) {// 初始化xml解析工廠DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 創建DocumentBuilderDocumentBuilder builder = null;try {builder = factory.newDocumentBuilder();} catch (ParserConfigurationException e) {e.printStackTrace();}// 創建DocumentDocument doc = builder.newDocument();// standalone用來表示該文件是否呼叫其它外部的文件。若值是 ”yes” 表示沒有呼叫外部文件doc.setXmlStandalone(true);// 創建一個根節點// 說明:// doc.createElement("元素名")、element.setAttribute("屬性名","屬性值")、element.setTextContent("標簽間內容")Element diagram = doc.createElement("diagram");diagram.setAttribute("id", "");diagram.setAttribute("tcn", "");// 創建根節點第一個子節點Element mxGraphModel = doc.createElement("mxGraphModel");diagram.appendChild(mxGraphModel);Element root = doc.createElement("root");mxGraphModel.appendChild(root);Element mxCell1 = doc.createElement("mxCell");mxCell1.setAttribute("id", "0");root.appendChild(mxCell1);Element mxCell2 = doc.createElement("mxCell");mxCell2.setAttribute("id", "1");mxCell2.setAttribute("parent", "0");root.appendChild(mxCell2);//根據圖的id獲取圖中節點//List<Map<String,Object>> transList = trans// 添加根節點 doc.appendChild(diagram);return doc;}public static void main(String[] args) {Document document= createDocument();System.out.println(getXmlStrByDocument(document));}public static Document getDocument(List<Map<String, Object>> newNodeList,String graphId) {// 初始化xml解析工廠DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 創建DocumentBuilderDocumentBuilder builder = null;try {builder = factory.newDocumentBuilder();} catch (ParserConfigurationException e) {e.printStackTrace();}// 創建DocumentDocument doc = builder.newDocument();// standalone用來表示該文件是否呼叫其它外部的文件。若值是 ”yes” 表示沒有呼叫外部文件doc.setXmlStandalone(true);// 創建一個根節點// 說明:// doc.createElement("元素名")、element.setAttribute("屬性名","屬性值")、element.setTextContent("標簽間內容")Element diagram = doc.createElement("diagram");diagram.setAttribute("id", graphId);diagram.setAttribute("tcn", "");// 創建根節點第一個子節點Element mxGraphModel = doc.createElement("mxGraphModel");diagram.appendChild(mxGraphModel);Element root = doc.createElement("root");mxGraphModel.appendChild(root);Element mxCell1 = doc.createElement("mxCell");mxCell1.setAttribute("id", "0");root.appendChild(mxCell1);Element mxCell2 = doc.createElement("mxCell");mxCell2.setAttribute("id", "1");mxCell2.setAttribute("parent", "0");root.appendChild(mxCell2);for (Map<String, Object> node : newNodeList) {handleNode(root,doc,node);}// 添加根節點 doc.appendChild(diagram);return doc;}private static void handleNode(Element root, Document doc, Map<String, Object> node) {Element mxCell = doc.createElement((String) node.get("nodeName"));Object as = node.get("as");Object width = node.get("width");Object x = node.get("x");Object y = node.get("y");Object style = node.get("style");Object nodeId = node.get("nodeId");Object height = node.get("height");Object parent = node.get("parent");Object relative = node.get("relative");Object vertex = node.get("vertex");Object value = node.get("value");Object edge = node.get("edge");Object source = node.get("source");Object target = node.get("target");if(value!=null && !"".equals(value)){mxCell.setAttribute("value", (String) value);}if(edge!=null && !"".equals(edge)){mxCell.setAttribute("edge", (String) edge);}if(source!=null && !"".equals(source)){mxCell.setAttribute("source", (String) source);}if(target!=null && !"".equals(target)){mxCell.setAttribute("target", (String) target);}if(as!=null && !"".equals(as)){mxCell.setAttribute("as", (String) as);}if(width!=null && !"".equals(width)){mxCell.setAttribute("width", (String) width);}if(x!=null && !"".equals(x)){mxCell.setAttribute("x", (String) x);}if(y!=null && !"".equals(y)){mxCell.setAttribute("y", (String) y);}if(style!=null && !"".equals(style)){mxCell.setAttribute("style", (String) style);}if(nodeId!=null && !"".equals(nodeId)){mxCell.setAttribute("id", (String) nodeId);}if(parent!=null && !"".equals(parent)){mxCell.setAttribute("parent", (String) parent);}if(height!=null && !"".equals(height)){mxCell.setAttribute("height", (String) height);}if(relative!=null && !"".equals(relative)){mxCell.setAttribute("relative", (String) relative);}if(vertex!=null && !"".equals(vertex)){mxCell.setAttribute("vertex", (String) vertex);}root.appendChild(mxCell);Object child = node.get("child");if(child!=null){List<Map<String, Object>> childNodeList = (List<Map<String, Object>>) child;for (Map<String, Object> map : childNodeList) {handleNode(mxCell, doc, map); }}}}

?這個是我寫的一個工具類,包括解析xml的方法,也有些封裝成xml的方法。

下面是解析xml并將其保存到數據庫的方法

@RequestMapping(value="/save2")@ResponseBodyprotected void save2(HttpServletResponse response,HttpServletRequest request,@RequestParam String graphXml) throws Exception{String xml = StringEscapeHelper.decode(graphXml);System.out.println(xml);Document current = mxXmlUtils.parseXml(xml);String graphId = "6ed10c4036f245b8bf78e1141d85e23b";//current.getDocumentElement().getAttribute("id");System.out.println("graphId:"+graphId);transService.deleteGraphById(graphId);List<Map<String, Object>> nodeMapList = DocumentUtil.parseDocument(current);for (Map<String, Object> trans : nodeMapList) {System.out.println(trans);transService.insert(trans);}try{PrintWriter out=response.getWriter();String result="songyan";out.write(result);out.flush();out.close();}catch (Exception e){e.printStackTrace();throw new Exception(e.getMessage());}}

?

?這里我是給每個圖一個唯一的id,每次保存的時候都把之前的節點信息刪除掉,再根據解析出來的節點信息,保存節點。

(5)節點信息封裝成mxgraph可以解析的xml

下面是從數據庫讀取節點信息,并將其轉換成xml的方法:

@ResponseBody@RequestMapping(method = RequestMethod.POST, value = "/open")protected void open(HttpServletRequest request) throws Exception {//獲取圖的idString graphId = request.getParameter("graphId");System.out.println("graphId::"+graphId);//獲取節點對象List<Map<String,Object>> nodeList = transService.getTransListByGraphId(graphId);List<Map<String,Object>> newNodeList = new ArrayList<Map<String,Object>>();for (Map<String, Object> node : nodeList) {Map nodeMap = node;String nodeId = (String) node.get("nodeId");//查詢子節點List<Map<String,Object>> childNodeList = getChildNodes(graphId,nodeId);if(childNodeList!=null && childNodeList.size()!=0){nodeMap.put("child", childNodeList);newNodeList.add(nodeMap);}}System.out.println(newNodeList);//獲取圖的document對象Document document = DocumentUtil.getDocument(newNodeList,graphId);//獲取xmlString graphXml = DocumentUtil.getXmlStrByDocument(document);System.out.println(graphXml);JsonUtils.responseXml(StringEscapeHelper.encode(graphXml));}

?

(6)頁面渲染xml,回顯成圖(普通的html,js中顯示正常,集成到VUE里面之后發現不報錯,也不顯示,針對VUE的處理會在下面說明)

var xml = '<diagram id="" tcn=""><mxGraphModel><root><Workflow value="Diagram" id="0"><mxCell/></Workflow><Layer value="Default Layer" id="1"><mxCell parent="0"/></Layer><mxCell id="2" value="Hello, World!" parent="1" vertex="1"><mxGeometry x="120" y="90" width="80" height="40" as="geometry"/></mxCell></root></mxGraphModel></diagram>'; var doc = mxUtils.parseXml(xml); var codec = new mxCodec(doc); codec.decode(doc.documentElement.firstChild, graph.getModel());

(7)Vue引入mxGraph(引入的方法很重要)

  1)在項目的src目錄下創建文件夾magraph,在mxgraph文件夾創建index.js,Graph.js兩個文件

  

  index.js內容:

import mx from 'mxgraph' const mxgraph = mx({mxBasePath: '/static/mxgraph' }) // decode bug https://github.com/jgraph/mxgraph/issues/49 window.mxGraph = mxgraph.mxGraph window.mxGraphModel = mxgraph.mxGraphModel window.mxEditor = mxgraph.mxEditor window.mxGeometry = mxgraph.mxGeometry window.mxDefaultKeyHandler = mxgraph.mxDefaultKeyHandler window.mxDefaultPopupMenu = mxgraph.mxDefaultPopupMenu window.mxStylesheet = mxgraph.mxStylesheet window.mxDefaultToolbar = mxgraph.mxDefaultToolbar export default mxgraph

?

  Graph.js內容:

import mxgraph from './index'; import _ from 'lodash';const {mxGraph,mxVertexHandler,mxConstants,mxCellState,mxPerimeter,mxCellEditor,mxGraphHandler,mxEvent,mxEdgeHandler,mxShape,mxConnectionConstraint,mxPoint,mxEventObject,mxCodec,mxObjectCodec,mxUtils,mxImageExport,mxXmlCanvas2D,mxCodecRegistry, } = mxgraph;Object.assign(mxEvent, {EDGE_START_MOVE: 'edgeStartMove',VERTEX_START_MOVE: 'vertexStartMove', });let pokeElementIdSeed = 0;// export class PokeElement { // constructor(element) { // this.id = pokeElementIdSeed; // pokeElementIdSeed++; // this.element = element; // this.normalType = ''; // } // } export class Graph extends mxGraph {static getStyleDict(cell) {return _.compact(cell.getStyle().split(';')).reduce((acc, item) => {const [key, value] = item.split('=');acc[key] = value;return acc;}, {});}static convertStyleToString(styleDict) {const style = Object.entries(styleDict).map(([key, value]) => `${key}=${value}`).join(';').replace(/=undefined/g, '');return `${style};`;}static getCellPosition(cell) {return _.pick(cell.getGeometry(), ['x', 'y']);}constructor(container) {super(container);this._init();}_init() {this._setDefaultConfig();this._configConstituent();this._putVertexStyle();this._setDefaultEdgeStyle();this._setAnchors();this._configCustomEvent();// this._configCoder(); }_configConstituent() {// Redirects selection to parentthis.selectCellForEvent = (...args) => {const [cell] = args;if (this.isPart(cell)) {args[0] = this.model.getParent(cell);mxGraph.prototype.selectCellForEvent.call(this, args);return;}mxGraph.prototype.selectCellForEvent.apply(this, args);};/*** Redirects start drag to parent.*/const graphHandlerGetInitialCellForEvent = mxGraphHandler.prototype.getInitialCellForEvent;mxGraphHandler.prototype.getInitialCellForEvent = function getInitialCellForEvent(...args) {// this 是 mxGraphHandlerlet cell = graphHandlerGetInitialCellForEvent.apply(this, args);if (this.graph.isPart(cell)) {cell = this.graph.getModel().getParent(cell);}return cell;};}_setDefaultConfig() {this.setConnectable(true);mxEvent.disableContextMenu(this.container);// 固定節點大小this.setCellsResizable(false);// 編輯時按回車鍵不換行,而是完成輸入this.setEnterStopsCellEditing(true);// 編輯時按 escape 后完成輸入mxCellEditor.prototype.escapeCancelsEditing = false;// 失焦時完成輸入mxCellEditor.prototype.blurEnabled = true;// 禁止節點折疊this.foldingEnabled = false;// 文本包裹效果必須開啟此配置this.setHtmlLabels(true);// 拖拽過程對齊線mxGraphHandler.prototype.guidesEnabled = true;// 禁止游離線條this.setDisconnectOnMove(false);this.setAllowDanglingEdges(false);mxGraph.prototype.isCellMovable = cell => !cell.edge;// 禁止調整線條彎曲度this.setCellsBendable(false);// 禁止從將label從線條上拖離mxGraph.prototype.edgeLabelsMovable = false;}_putVertexStyle() {const normalTypeStyle = {[mxConstants.STYLE_SHAPE]: mxConstants.SHAPE_IMAGE,[mxConstants.STYLE_PERIMETER]: mxPerimeter.RectanglePerimeter,};this.getStylesheet().putCellStyle('normalType', normalTypeStyle);const nodeStyle = {// 圖片樣式參考這個例子// https://github.com/jinzhanye/mxgraph-demos/blob/master/src/06.image.html [mxConstants.STYLE_SHAPE]: mxConstants.SHAPE_LABEL,[mxConstants.STYLE_PERIMETER]: mxPerimeter.RectanglePerimeter,[mxConstants.STYLE_ROUNDED]: true,[mxConstants.STYLE_ARCSIZE]: 6, // 設置圓角程度 [mxConstants.STYLE_STROKECOLOR]: '#333333',[mxConstants.STYLE_FONTCOLOR]: '#333333',[mxConstants.STYLE_FILLCOLOR]: '#ffffff',// [mxConstants.STYLE_LABEL_BACKGROUNDCOLOR]: 'none',[mxConstants.STYLE_ALIGN]: mxConstants.ALIGN_CENTER,[mxConstants.STYLE_VERTICAL_ALIGN]: mxConstants.ALIGN_TOP,[mxConstants.STYLE_IMAGE_ALIGN]: mxConstants.ALIGN_CENTER,[mxConstants.STYLE_IMAGE_VERTICAL_ALIGN]: mxConstants.ALIGN_TOP,[mxConstants.STYLE_IMAGE_WIDTH]: '72',[mxConstants.STYLE_IMAGE_HEIGHT]: '72',[mxConstants.STYLE_SPACING_TOP]: '100',[mxConstants.STYLE_SPACING]: '8',};this.getStylesheet().putCellStyle('node', nodeStyle);// 設置選中狀態節點的邊角為圓角,默認是直角const oldCreateSelectionShape = mxVertexHandler.prototype.createSelectionShape;mxVertexHandler.prototype.createSelectionShape = function createSelectionShape(...args) {const res = oldCreateSelectionShape.apply(this, args);res.isRounded = true;// style 屬性來自 mxShape , mxRectangle 繼承自 mxShaperes.style = {arcSize: 6,};return res;};}_setDefaultEdgeStyle() {const style = this.getStylesheet().getDefaultEdgeStyle();Object.assign(style, {[mxConstants.STYLE_ROUNDED]: true, // 設置線條拐彎處為圓角[mxConstants.STYLE_STROKEWIDTH]: '2',[mxConstants.STYLE_STROKECOLOR]: '#333333',[mxConstants.STYLE_EDGE]: mxConstants.EDGESTYLE_ORTHOGONAL,[mxConstants.STYLE_FONTCOLOR]: '#33333',[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR]: '#ffa94d',});// 設置拖拽線的過程出現折線,默認為直線this.connectionHandler.createEdgeState = () => {const edge = this.createEdge();return new mxCellState(this.view, edge, this.getCellStyle(edge));};}_setAnchors() {// 禁止從節點中心拖拽出線條this.connectionHandler.isConnectableCell = () => false;mxEdgeHandler.prototype.isConnectableCell = () => false;// Overridden to define per-shape connection pointsmxGraph.prototype.getAllConnectionConstraints = (terminal) => {if (terminal != null && terminal.shape != null) {if (terminal.shape.stencil != null) {if (terminal.shape.stencil != null) {return terminal.shape.stencil.constraints;}} else if (terminal.shape.constraints != null) {return terminal.shape.constraints;}}return null;};// Defines the default constraints for all shapesmxShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), true),new mxConnectionConstraint(new mxPoint(0, 1), true),new mxConnectionConstraint(new mxPoint(1, 0), true),new mxConnectionConstraint(new mxPoint(1, 1), true),new mxConnectionConstraint(new mxPoint(0.25, 0), true),new mxConnectionConstraint(new mxPoint(0.5, 0), true),new mxConnectionConstraint(new mxPoint(0.75, 0), true),new mxConnectionConstraint(new mxPoint(0, 0.25), true),new mxConnectionConstraint(new mxPoint(0, 0.5), true),new mxConnectionConstraint(new mxPoint(0, 0.75), true),new mxConnectionConstraint(new mxPoint(1, 0.25), true),new mxConnectionConstraint(new mxPoint(1, 0.5), true),new mxConnectionConstraint(new mxPoint(1, 0.75), true),new mxConnectionConstraint(new mxPoint(0.25, 1), true),new mxConnectionConstraint(new mxPoint(0.5, 1), true),new mxConnectionConstraint(new mxPoint(0.75, 1), true)];}_configCustomEvent() {const graph = this;const oldStart = mxEdgeHandler.prototype.start;mxEdgeHandler.prototype.start = function start(...args) {oldStart.apply(this, args);graph.fireEvent(new mxEventObject(mxEvent.EDGE_START_MOVE,'edge', this.state.cell,'source', this.isSource,));};const oldCreatePreviewShape = mxGraphHandler.prototype.createPreviewShape;mxGraphHandler.prototype.createPreviewShape = function createPreviewShape(...args) {graph.fireEvent(new mxEventObject(mxEvent.VERTEX_START_MOVE));return oldCreatePreviewShape.apply(this, args);};}_configCoder() {const codec = new mxObjectCodec(new PokeElement());codec.encode = function (enc, obj) {const node = enc.document.createElement('PokeElement');mxUtils.setTextContent(node, JSON.stringify(obj));return node;};codec.decode = function (dec, node, into) {const obj = JSON.parse(mxUtils.getTextContent(node));obj.constructor = PokeElement;return obj;};mxCodecRegistry.register(codec);}getDom(cell) {const state = this.view.getState(cell);return state.shape.node;}setStyle(cell, key, value) {const styleDict = Graph.getStyleDict(cell);styleDict[key] = value;const style = Graph.convertStyleToString(styleDict);this.getModel().setStyle(cell, style);}isPart(cell) {const state = this.view.getState(cell);const style = (state != null) ? state.style : this.getCellStyle(cell);return style.constituent === 1;}deleteSubtree(cell) {const cells = [];this.traverse(cell, true, (vertex) => {cells.push(vertex);return true;});this.removeCells(cells);}_restoreModel() {Object.values(this.getModel().cells).forEach(cell => {if (cell.vertex && cell.data) {cell.data = JSON.parse(cell.data);}});}// 將 data 變為字符串,否則還原時會報錯 _getExportModel() {const model = _.cloneDeep(this.getModel());Object.values(model.cells).forEach(cell => {if (cell.vertex && cell.data) {cell.data = JSON.stringify(cell.data);}});return model;}importModelXML(xmlTxt) {this.getModel().beginUpdate();try {const doc = mxUtils.parseXml(xmlTxt);const root = doc.documentElement;const dec = new mxCodec(root.ownerDocument);dec.decode(root, this.getModel());} finally {this.getModel().endUpdate();}this._restoreModel();}exportModelXML() {const enc = new mxCodec(mxUtils.createXmlDocument());const node = enc.encode(this._getExportModel());return mxUtils.getPrettyXml(node);}exportPicXML() {const xmlDoc = mxUtils.createXmlDocument();const root = xmlDoc.createElement('output');xmlDoc.appendChild(root);const { scale } = this.view;// 這個項目畫布邊寬為0,可以自行進行調整const border = 0;const bounds = this.getGraphBounds();const xmlCanvas = new mxXmlCanvas2D(root);xmlCanvas.translate(Math.floor((border / scale - bounds.x) / scale),Math.floor((border / scale - bounds.y) / scale),);xmlCanvas.scale(1);const imgExport = new mxImageExport();imgExport.drawState(this.getView().getState(this.model.root), xmlCanvas);const w = Math.ceil(bounds.width * scale / scale + 2 * border);const h = Math.ceil(bounds.height * scale / scale + 2 * border);const xml = mxUtils.getPrettyXml(root);return {xml,w,h,};} }let graph = {};export const destroyGraph = () => {graph.destroy();graph = {}; };export const genGraph = (container) => {graph = new Graph(container);return graph; };export const getGraph = () => graph; View Code

?

?

  2)在使用Vue的頁面引入

import mxgraph from "../../graph/index";const {mxGraph,mxClient,mxDragSource,mxCell,mxRubberband,mxVertexHandler,mxConstants,mxCellState,mxPerimeter,mxCellEditor,mxGraphHandler,mxEvent,mxEdgeHandler,mxShape,mxConnectionConstraint,mxPoint,mxEventObject,mxCodec,mxObjectCodec,mxUtils,mxImageExport,mxXmlCanvas2D,mxClipboard,mxCodecRegistry } = mxgraph;

  3)cnpm安裝

    xnpm install mxgraph

注:其他的方式可能也能引入但是有些功能可能不能用,比如xml渲染的時候不出錯但是也不顯示

  4)關于節點樣式的處理,拖拽生成圖的處理,右鍵生成菜單,右鍵刪除節點的功能如下

<template><el-container style="height: 500px; border: 1px solid #eee"><el-aside width="200px" style="background-color: rgb(238, 241, 246)"><el-header style="text-align: center; font-size: 16px;" class="left_header"><b>轉換管理</b></el-header><el-menu :default-openeds="['1']"><el-submenu index="1"><template slot="title"><i class="el-icon-menu"></i>輸入</template><el-menu-item-group><el-menu-item><span id="in1" class="itemstyle"></span><spanunselectable="on"qtip="從一個微軟的Excel文件里讀取數據. 兼容Excel 95, 97 and 2000."id="extdd-81">Excel輸入</span></el-menu-item><el-menu-item><span id="in2" class="itemstyle"></span><spanunselectable="on"qtip="從一個文本文件(幾種格式)里讀取數據{0}這些數據可以被傳遞到下一個步驟里..."id="extdd-84">文本文件輸入</span></el-menu-item><el-menu-item><span id="in3" class="itemstyle"></span><span unselectable="on" qtip="產生一些空記錄或相等的行." id="extdd-87">生成記錄</span></el-menu-item><el-menu-item><span id="in4" class="itemstyle"></span><span unselectable="on" qtip="Generate random value" id="extdd-90">生成隨機數</span></el-menu-item><el-menu-item><span id="in5" class="itemstyle"></span><spanunselectable="on"qtip="Enter rows of static data in a grid, usually for testing, reference or demo purpose"id="extdd-93">自定義常量數據</span></el-menu-item><el-menu-item><span id="in6" class="itemstyle"></span><span unselectable="on" qtip="獲取系統信息,例如時間、日期." id="extdd-96">獲取系統信息</span></el-menu-item><el-menu-item><span id="in7" class="itemstyle"></span><span unselectable="on" qtip="從數據庫表里讀取信息." id="extdd-99">表輸入</span></el-menu-item></el-menu-item-group></el-submenu><el-submenu index="2"><template slot="title"><i class="el-icon-menu"></i>輸出</template><el-menu-item-group><el-menu-item><span id="out1"></span><spanunselectable="on"qtip="Stores records into an Excel (XLS) document with formatting information."id="extdd-102">Excel輸出</span></el-menu-item><el-menu-item><span id="out2"></span><spanunselectable="on"qtip="Output SQL INSERT statements to file"id="extdd-105">SQL 文件輸出</span></el-menu-item><el-menu-item><span id="out3"></span><span unselectable="on" qtip="基于關鍵字刪除記錄" id="extdd-108">刪除</span></el-menu-item><el-menu-item><span id="out4"></span><span unselectable="on" qtip="基于關鍵字更新或插入記錄到數據庫." id="extdd-90">插入 / 更新</span></el-menu-item><el-menu-item><span id="out5"></span><spanunselectable="on"qtip="This step perform insert/update/delete in one go based on the value of a field. "id="extdd-93">數據同步</span></el-menu-item><el-menu-item><span id="out6"></span><span unselectable="on" qtip="寫記錄到一個文本文件." id="extdd-96">文本文件輸出</span></el-menu-item><el-menu-item><span id="out7"></span><span unselectable="on" qtip="基于關鍵字更新記錄到數據庫" id="extdd-99">更新</span></el-menu-item><el-menu-item><span id="out8"></span><span unselectable="on" qtip="寫信息到一個數據庫表" id="extdd-102">表輸出</span></el-menu-item></el-menu-item-group></el-submenu><el-submenu index="3"><template slot="title"><i class="el-icon-menu"></i>轉換</template><el-menu-item-group><el-menu-item><span id="trans1"></span><spanunselectable="on"qtip="Maps values of a certain field from one value to another"id="extdd-105">值映射</span></el-menu-item><el-menu-item><span id="trans2"></span><spanunselectable="on"qtip="Denormalises rows by looking up key-value pairs and by assigning them to new fields in the輸出 rows.{0}This method aggregates and needs the輸入 rows to be sorted on the grouping fields"id="extdd-108">列轉行</span></el-menu-item><el-menu-item><span id="trans3"></span><span unselectable="on" qtip="Strings cut (substring)." id="extdd-111">剪切字符串</span></el-menu-item><el-menu-item><span id="trans4"></span><spanunselectable="on"qtip="去除重復的記錄行,保持記錄唯一{0}這個僅僅基于一個已經排好序的輸入.{1}如果輸入沒有排序, 僅僅兩個連續的記錄行被正確處理."id="extdd-114">去除重復記錄</span></el-menu-item><el-menu-item><span id="trans5"></span><span unselectable="on" qtip="給記錄增加一到多個常量" id="extdd-117">增加常量</span></el-menu-item><el-menu-item><span id="trans6"></span><span unselectable="on" qtip="從序列獲取下一個值" id="extdd-120">增加序列</span></el-menu-item><el-menu-item><span id="trans7"></span><spanunselectable="on"qtip="Add a checksum column for each input row"id="extdd-123">增加校驗列</span></el-menu-item><el-menu-item><span id="trans8"></span><spanunselectable="on"qtip="選擇或移除記錄里的字。{0}此外,可以設置字段的元數據: 類型, 長度和精度."id="extdd-126">字段選擇</span></el-menu-item><el-menu-item><span id="trans9"></span><spanunselectable="on"qtip="Replace all occurences a word in a string with another word."id="extdd-129">字符串替換</span></el-menu-item><el-menu-item><span id="trans10"></span><span unselectable="on" qtip="基于字段值把記錄排序(升序或降序)" id="extdd-132">排序記錄</span></el-menu-item><el-menu-item><span id="trans11"></span><spanunselectable="on"qtip="Flattens consequetive rows based on the order in which they appear in the輸入 stream"id="extdd-135">行扁平化</span></el-menu-item><el-menu-item><span id="trans12"></span><spanunselectable="on"qtip="De-normalised information can be normalised using this step type."id="extdd-138">行轉列</span></el-menu-item></el-menu-item-group></el-submenu><el-submenu index="4"><template slot="title"><i class="el-icon-menu"></i>腳本</template><el-menu-item-group><el-menu-item><span id="scp1"></span><spanunselectable="on"qtip="This is a modified plugin for the Scripting Values with improved interface and performance. Written &amp; donated to open source by Martin Lange, Proconis : http://www.proconis.de"id="extdd-81">JavaScript代碼</span></el-menu-item><el-menu-item><span id="scp2"></span><span unselectable="on" qtip="執行一個SQL腳本, 另外,可以使用輸入的記錄作為參數" id="extdd-84">執行SQL腳本</span></el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><el-container><el-header style="text-align: left; font-size: 12px" class="right_header"><el-button type="primary" @click="clearGraph">清空</el-button><el-button type="primary" @click="lookXML">查看xml</el-button><el-button type="primary" @click="save">保存</el-button></el-header><el-main><div ref="graph_container" id="right"></div></el-main></el-container></el-container><!-- <div ref="graph_container"></div> --> </template><script> import mxgraph from "../../graph/index";const {mxGraph,mxClient,mxDragSource,mxCell,mxRubberband,mxVertexHandler,mxConstants,mxCellState,mxPerimeter,mxCellEditor,mxGraphHandler,mxEvent,mxEdgeHandler,mxShape,mxConnectionConstraint,mxPoint,mxEventObject,mxCodec,mxObjectCodec,mxUtils,mxImageExport,mxXmlCanvas2D,mxClipboard,mxCodecRegistry } = mxgraph;import api from "@/utils/api"; export default {data() {return {graph: null,undoMng: null};},name: "HelloWorld",props: {// msg: String },created() {},methods: {save() {var xml ='<diagram id="" tcn="">' +mxUtils.getXml(new mxCodec().encode(this.graph.getModel())) +"</diagram>";api("appserver/getAppServer", "post", { gid: "01" }).then(response => {console.log("response");consoele.log(response);/* this.temp.name = response.namethis.temp.details = response.detailsthis.temp.iconurl = response.iconurlthis.temp.operateType = 'U'this.temp.flowtype = response.flowtypethis.imageUrl = response.iconshowurl */// this.isLoading = false }).catch(() => {//this.isLoading = false });},clearGraph(graph) {alert("clear");this.undoMng.undo();this.undoMng.redo();},createDragSource(graph) {//創建輸入拖動源var in1 = this.createDragImage(graph,"in1","./images/XLI.png","EXCEL輸入");var in2 = this.createDragImage(graph,"in2","./images/TFI.png","文本文件輸入");var in3 = this.createDragImage(graph,"in3","./images/GEN.png","生成記錄");var in4 = this.createDragImage(graph,"in4","./images/RVA.png","生成隨機數");var in5 = this.createDragImage(graph,"in5","./images/GNR.png","自定義常量數據");var in6 = this.createDragImage(graph,"in6","./images/SYS.png","獲取系統信息");var in7 = this.createDragImage(graph,"in7","./images/TIP.png","表輸入");//創建輸出拖動源var out1 = this.createDragImage(graph,"out1","./images/XLO.png","Excel輸出");var out2 = this.createDragImage(graph,"out2","./images/SFO.png","SQL 文件輸出");var out3 = this.createDragImage(graph,"out3","./images/Delete.png","刪除");var out4 = this.createDragImage(graph,"out4","./images/INU.png","插入 / 更新");var out5 = this.createDragImage(graph,"out5","./images/SAM.png","數據同步");var out6 = this.createDragImage(graph,"out6","./images/TFO.png","文本文件輸出");var out7 = this.createDragImage(graph,"out7","./images/UPD.png","更新");var out8 = this.createDragImage(graph,"out8","./images/TOP.png","表輸出");//創建轉換拖動源var trans1 = this.createDragImage(graph,"trans1","./images/VMAP.png","值映射");var trans2 = this.createDragImage(graph,"trans2","./images/UNP.png","列轉行");var trans3 = this.createDragImage(graph,"trans3","./images/SRC.png","剪切字符串");var trans4 = this.createDragImage(graph,"trans4","./images/UNQ.png","去除重復記錄");var trans5 = this.createDragImage(graph,"trans5","./images/CST.png","增加常量");var trans6 = this.createDragImage(graph,"trans6","./images/SEQ.png","增加序列");var trans7 = this.createDragImage(graph,"trans7","./images/CSM.png","增加校驗列");var trans8 = this.createDragImage(graph,"trans8","./images/SEL.png","字段選擇");var trans9 = this.createDragImage(graph,"trans9","./images/RST.png","字符串替換");var trans10 = this.createDragImage(graph,"trans10","./images/SRT.png","排序記錄");var trans11 = this.createDragImage(graph,"trans11","./images/FLA.png","行扁平化");var trans12 = this.createDragImage(graph,"trans12","./images/NRM.png","行轉列");//創建腳本拖動源var scp1 = this.createDragImage(graph,"scp1","./images/SCR_mod.png","scp1");var scp2 = this.createDragImage(graph,"scp2","./images/SQL.png","scp2");},paseXML(graph) {var xml ='<mxGraphModel> <root> <mxCell id="0"/> <mxCell id="1" parent="0"/> <mxCell id="2" value="EXCEL輸入" style="in1" vertex="1" parent="1"> <mxGeometry x="100" y="110" width="50" height="50" as="geometry"/> </mxCell> <mxCell id="3" value="文本文件輸入" style="in2" vertex="1" parent="1"> <mxGeometry x="380" y="130" width="50" height="50" as="geometry"/> </mxCell> <mxCell id="4" value="生成隨機數" style="in4" vertex="1" parent="1"> <mxGeometry x="210" y="350" width="50" height="50" as="geometry"/> </mxCell> <mxCell id="6" edge="1" parent="1" source="2" target="4"> <mxGeometry relative="1" as="geometry"/> </mxCell> <mxCell id="7" edge="1" parent="1" source="4" target="3"> <mxGeometry relative="1" as="geometry"/> </mxCell> </root> </mxGraphModel>';var doc = mxUtils.parseXml(xml);var codec = new mxCodec(doc);codec.decode(doc.documentElement, graph.getModel());},RightMenu(graph) {var container = document.getElementById("right");//禁用瀏覽器自帶的右鍵事件 mxEvent.disableContextMenu(container);// 使用本地函數安裝彈出菜單處理程序graph.popupMenuHandler.factoryMethod = function(menu, cell, evt) {return createPopupMenu(graph, menu, cell, evt);};//創建右鍵的菜單function createPopupMenu(graph, menu, cell, evt) {if (cell != null) {menu.addItem("復制步驟", "", function() {var cells = new Array();cells = graph.getSelectionCells();console.log("graph");console.log(graph);console.log("cells");console.log(cells);console.log("mxClipboard", mxClipboard);mxClipboard.copy(graph, cells);});}menu.addSeparator();menu.addItem("刪除步驟", "", function() {var cells = new Array();cells = graph.getSelectionCells();graph.removeCells(cells);});}},lookXML() {var encoder = new mxCodec();var node = encoder.encode(this.graph.getModel());const h = this.$createElement;this.$msgbox({title: "xml",message: h("p", null, [h("div",{style:"overflow-y:auto; overflow-x:auto; width:400px; max-height:400px;"},mxUtils.getPrettyXml(node))]),showCancelButton: true,confirmButtonText: "確定",cancelButtonText: "取消"});},getStyle(graph, url, styleName) {// 聲明一個objectvar style = {};// 克隆一個objectstyle = mxUtils.clone(style);style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_LABEL; // 不設置這個屬性 背景圖片不出來// 邊框顏色style[mxConstants.STYLE_STROKECOLOR] = "#15428b";//圓角style[mxConstants.STYLE_ROUNDED] = "1";// 邊框大小style[mxConstants.STYLE_STROKEWIDTH] = "0.5px";// 字體顏色style[mxConstants.STYLE_FONTCOLOR] = "#000";// 文字水平方式style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_right;// 文字垂直對齊style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_TOP;// 字體大小style[mxConstants.STYLE_FONTSIZE] = 14;style[mxConstants.STYLE_FILLCOLOR] = "transparent";// 底圖水平對齊style[mxConstants.STYLE_IMAGE_ALIGN] = mxConstants.ALIGN_LEFT;// 底圖垂直對齊style[mxConstants.STYLE_IMAGE_VERTICAL_ALIGN] = mxConstants.ALIGN_TOP;// 圖片路徑//style[mxConstants.STYLE_IMAGE] = 'images/icons48/gear.png';style[mxConstants.STYLE_IMAGE] = url; //'./images/i_assignedSlave.png';// 背景圖片寬style[mxConstants.STYLE_IMAGE_WIDTH] = 40;// 背景圖片高style[mxConstants.STYLE_IMAGE_HEIGHT] = 40;// 上間距設置// 即使下邊定義了全局設置,但這里單獨設置上邊間距仍單獨有效// style[mxConstants.STYLE_SPACING_TOP] = 'spacingTop';// 四邊間距設置style[mxConstants.STYLE_SPACING] = 1;style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] =mxConstants.ALIGN_BOTTOM;graph.getStylesheet().putCellStyle(styleName, style);},createDragImage(graph, id, image, text) {var img = mxUtils.createImage(image);img.style.width = "30px";img.style.height = "30px";img.style.margin = "0px";document.getElementById(id).appendChild(img);var style = this.getStyle(graph, image, id);// 檢查圖形中是否包含對應的elt節點function containsElt(graph, elt) {while (elt != null) {if (elt == graph.container) {return true;}elt = elt.parentNode;}return false;}// 在給定的位置插入一個元素var funct1 = function(graph, evt, target, x, y) {/* var prefix = '';prefix = prefix+'verticalLabelPosition=bottom;verticalAlign=top;STYLE_STROKEWIDTH=1px;'; */var cell = new mxCell(text, new mxGeometry(0, 0, 50, 50), id);cell.vertex = true;var cells = graph.importCells([cell], x, y, target); //插入元素、位置、大小 console.log(cells.getStyle);};// 禁用IE瀏覽器中的DnD功能(這是為了跨瀏覽器平臺而設計的,見下文)if (mxClient.IS_IE) {mxEvent.addListener(img, "dragstart", function(evt) {evt.returnValue = false;});}// 創建拖動源的預覽var dragElt = document.createElement("div");dragElt.style.border = "dashed black 1px";dragElt.style.width = "120px";dragElt.style.height = "40px";// 在點擊拖動源圖標時提供預覽。 預覽是提供的僅僅是拖動源的圖片// 只有拖動源到容器內時才會顯示元素的坐標預覽var ds = mxUtils.makeDraggable(img,graph,funct1,dragElt,null,null,graph.autoscroll,true);//從拖動源拖動時顯示導航線。//注意,對圖形中已存在的元素拖動時顯示導航線不在本方法約束范圍。ds.isGuidesEnabled = function() {return graph.graphHandler.guidesEnabled;};//從拖動源拖動元素到圖形以外的區域時,顯示拖動源圖片預覽ds.createDragElement = mxDragSource.prototype.createDragElement;}},// /item1 mounted() {var graph = new mxGraph(this.$refs.graph_container);graph.setConnectable(true);new mxRubberband(graph);var parent = graph.getDefaultParent();this.graph = graph;//創建拖拽源this.createDragSource(graph);//頁面初始化this.paseXML(graph);//右鍵菜單定義this.RightMenu(graph);} }; </script><style scoped> .left_header {font-weight: 500;margin: 0 auto;padding: 15px; } .right_header {margin: auto 0;background-color: #e9edf1;padding: 10px;padding-left: 15px; } #right {height: 100%;position: relative;overflow: hidden;width: 100%;height: 100%;background: url("/images/grid.gif");cursor: default; }.el-menu-item-group__title {padding: 0px 0 7px 20px;line-height: normal;font-size: 12px;color: #909399; } </style> View Code

?

效果圖

?

轉載于:https://www.cnblogs.com/excellencesy/p/11385806.html

總結

以上是生活随笔為你收集整理的mxgraph初体验的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。