关键词:
【中文标题】如何获取连接的mxgraph之间的父子关系【英文标题】:How to get the parent child relationship between connected mxgraph 【发布时间】:2019-09-25 10:33:31 【问题描述】:我正在尝试简化连接 mxgraph
之间的关系
问题:一旦绘制了图表,我正在尝试获得简化的关系。
我正在尝试获取 json 中连接节点之间的关系。
注意:解决方案必须适用于每个绘制状态。
这里是代码笔:
https://codepen.io/eabangalore/pen/pmELpL
我想从上面的代码 sn-p 中得到关系。
预期输出(来自绘制的关系):
[
"id":0,"parent":"#","text":"A","child":["cid":1,"connectionText":"Bangalore"],
"id":1,"parent":0,"text":"B","child":["cid":2,"connectionText":""],
"id":2,"parent":1,"text":"C","child":["cid":null,"connectionText":""]
];
请参考codepen,如下sn-p不工作。
<!--
Copyright (c) 2006-2013, JGraph Ltd
Dynamic toolbar example for mxGraph. This example demonstrates changing the
state of the toolbar at runtime.
-->
<html>
<head>
<title>Toolbar example for mxGraph</title>
<!-- Sets the basepath for the library if not in same directory -->
<script type="text/javascript">
mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
function setGraphData()
var graphState ="tagName":"mxGraphModel","children":["tagName":"root","children":["tagName":"mxCell","attributes":"id":"0","tagName":"mxCell","attributes":"id":"1","parent":"0","tagName":"mxCell","attributes":"id":"2","value":"A","style":"","vertex":"1","parent":"1","children":["tagName":"mxGeometry","attributes":"x":"271.56251525878906","y":"82.44792175292969","width":"100","height":"40","as":"geometry"],"tagName":"mxCell","attributes":"id":"3","value":"B","style":"","vertex":"1","parent":"1","children":["tagName":"mxGeometry","attributes":"x":"678.2291717529297","y":"106.89236450195312","width":"100","height":"40","as":"geometry"],"tagName":"mxCell","attributes":"id":"4","value":"Bangalore","edge":"1","parent":"1","source":"2","target":"3","children":["tagName":"mxGeometry","attributes":"relative":"1","as":"geometry"],"tagName":"mxCell","attributes":"id":"5","value":"C","style":"","vertex":"1","parent":"1","children":["tagName":"mxGeometry","attributes":"x":"1013.7847747802734","y":"83.55902862548828","width":"100","height":"40","as":"geometry"],"tagName":"mxCell","attributes":"id":"6","edge":"1","parent":"1","source":"3","target":"5","children":["tagName":"mxGeometry","attributes":"relative":"1","as":"geometry"]]];
localStorage.setItem('graphState',JSON.stringify(graphState));
function html2json(html)
if(html.nodeType==3)
return
"tagName":"#text",
"content":html.textContent
var element =
"tagName":html.tagName
;
if(html.getAttributeNames().length>0)
element.attributes = html.getAttributeNames().reduce(
function(acc,at)acc[at]=html.getAttribute(at); return acc;,
);
if(html.childNodes.length>0)
element.children = Array.from(html.childNodes)
.filter(
function(el)
return el.nodeType!=3
||el.textContent.trim().length>0
)
.map(function(el)return html2json(el););
return element;
function json2html(json)
var xmlDoc = document.implementation.createDocument(null, json.tagName);
var addAttributes = function(jsonNode, node)
if(jsonNode.attributes)
Object.keys(jsonNode.attributes).map(
function(name)
node.setAttribute(name,jsonNode.attributes[name]);
);
var addChildren = function(jsonNode,node)
if(jsonNode.children)
jsonNode.children.map(
function(jsonChildNode)
json2htmlNode(jsonChildNode,node);
);
var json2htmlNode = function(jsonNode,parent)
if(jsonNode.tagName=="#text")
return xmlDoc.createTextNode(jsonNode.content);
var node = xmlDoc.createElement(jsonNode.tagName);
addAttributes(jsonNode,node);
addChildren(jsonNode,node);
parent.appendChild(node);
addAttributes(json,xmlDoc.firstElementChild);
addChildren(json,xmlDoc.firstElementChild);
return xmlDoc;
</script>
<!-- Loads and initializes the library -->
<script type="text/javascript" src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script>
<!-- Example code -->
<script type="text/javascript">
// Program starts here. Creates a sample graph in the
// DOM node with the specified ID. This function is invoked
// from the onLoad event handler of the document (see below).
function main()
setGraphData();
// Checks if browser is supported
if (!mxClient.isBrowserSupported())
// Displays an error message if the browser is
// not supported.
mxUtils.error('Browser is not supported!', 200, false);
else
// Defines an icon for creating new connections in the connection handler.
// This will automatically disable the highlighting of the source vertex.
mxConnectionHandler.prototype.connectImage = new mxImage('images/connector.gif', 16, 16);
// Creates the div for the toolbar
var tbContainer = document.createElement('div');
tbContainer.style.position = 'absolute';
tbContainer.style.overflow = 'hidden';
tbContainer.style.padding = '2px';
tbContainer.style.left = '0px';
tbContainer.style.top = '0px';
tbContainer.style.width = '24px';
tbContainer.style.bottom = '0px';
document.body.appendChild(tbContainer);
// Creates new toolbar without event processing
var toolbar = new mxToolbar(tbContainer);
toolbar.enabled = false
// Creates the div for the graph
var container = document.createElement('div');
container.style.position = 'absolute';
container.style.overflow = 'hidden';
container.style.left = '24px';
container.style.top = '0px';
container.style.right = '0px';
container.style.bottom = '0px';
container.style.background = 'url("editors/images/grid.gif")';
document.body.appendChild(container);
// Workaround for Internet Explorer ignoring certain styles
if (mxClient.IS_QUIRKS)
document.body.style.overflow = 'hidden';
new mxDivResizer(tbContainer);
new mxDivResizer(container);
// Creates the model and the graph inside the container
// using the fastest rendering available on the browser
var model = new mxGraphModel();
var graph = new mxGraph(container, model);
// Enables new connections in the graph
graph.setConnectable(true);
graph.setMultigraph(false);
// Stops editing on enter or escape keypress
var keyHandler = new mxKeyHandler(graph);
var rubberband = new mxRubberband(graph);
var addVertex = function(icon, w, h, style)
var vertex = new mxCell(null, new mxGeometry(0, 0, w, h), style);
vertex.setVertex(true);
var img = addToolbarItem(graph, toolbar, vertex, icon);
img.enabled = true;
graph.getSelectionModel().addListener(mxEvent.CHANGE, function()
var tmp = graph.isSelectionEmpty();
mxUtils.setOpacity(img, (tmp) ? 100 : 20);
img.enabled = tmp;
);
;
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rectangle.gif', 100, 40, '');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rounded.gif', 100, 40, 'shape=rounded');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/ellipse.gif', 40, 40, 'shape=ellipse');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rhombus.gif', 40, 40, 'shape=rhombus');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/triangle.gif', 40, 40, 'shape=triangle');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/cylinder.gif', 40, 40, 'shape=cylinder');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/actor.gif', 30, 40, 'shape=actor');
// read state on load
if(window.localStorage.graphState)
var doc = json2html(JSON.parse(localStorage.graphState));
var dec = new mxCodec(doc);
dec.decode(doc.documentElement, graph.getModel());
// save state on change
graph.getModel().addListener('change',function()
var codec = new mxCodec();
window.localStorage.graphState = JSON.stringify(html2json(codec.encode(
graph.getModel()
)));
);
function addToolbarItem(graph, toolbar, prototype, image)
// Function that is executed when the image is dropped on
// the graph. The cell argument points to the cell under
// the mousepointer if there is one.
var funct = function(graph, evt, cell, x, y)
graph.stopEditing(false);
var vertex = graph.getModel().cloneCell(prototype);
vertex.geometry.x = x;
vertex.geometry.y = y;
graph.addCell(vertex);
graph.setSelectionCell(vertex);
// Creates the image which is used as the drag icon (preview)
var img = toolbar.addMode(null, image, function(evt, cell)
var pt = this.graph.getPointForEvent(evt);
funct(graph, evt, cell, pt.x, pt.y);
);
// Disables dragging if element is disabled. This is a workaround
// for wrong event order in IE. Following is a dummy listener that
// is invoked as the last listener in IE.
mxEvent.addListener(img, 'mousedown', function(evt)
// do nothing
);
// This listener is always called first before any other listener
// in all browsers.
mxEvent.addListener(img, 'mousedown', function(evt)
if (img.enabled == false)
mxEvent.consume(evt);
);
mxUtils.makeDraggable(img, graph, funct);
return img;
</script>
</head>
<!-- Calls the main function after the page has loaded. Container is dynamically created. -->
<body onload="main();" >
</body>
</html>
请帮助我提前谢谢!!!
【问题讨论】:
【参考方案1】:查看此 CodePen 链接,其中包含您提供的 sn-p 的修改版本。在其中,您可以添加新元素和更改文本,并查看表示图中关系的更新 json 字符串:https://codepen.io/tien-q-nguyen2/pen/GaQXBO
从我第一次发布这个答案时,我还稍微编辑了这个函数。
注意:根据您在原始问题中输入的预期输出,每个顶点元素只有一个父元素(在您给出的示例中为 "id":1,"parent":0
function getNodesFrom(graph)
var cells = graph.getModel().cells;
var vertices = [], edges = [];
for (var key in cells)
if (cells[key].isVertex())
vertices.push(cells[key]);
else if (cells[key].isEdge())
edges.push(cells[key]);
var simpleVertices = [], simpleEdges = [];
var newIndex = 0;
var newIndexOf = [];
vertices.forEach(function(vertex)
simpleVertices.push(id: newIndex, value: vertex.value);
newIndexOf[vertex.id] = newIndex++;
);
edges.forEach(function(edge)
if (edge.target === null || edge.source === null) return;
simpleEdges.push(
parentId: newIndexOf[edge.source.id],
childId: newIndexOf[edge.target.id],
value: edge.value
);
);
var edgesForParentIndex = [];
var edgesForChildIndex = [];
simpleEdges.forEach(function(edge)
if (edgesForParentIndex[edge.parentId] === undefined)
edgesForParentIndex[edge.parentId] = [];
edgesForParentIndex[edge.parentId].push(edge);
if (edgesForChildIndex[edge.childId] === undefined)
edgesForChildIndex[edge.childId] = [];
edgesForChildIndex[edge.childId].push(edge);
);
var nodes = [];
simpleVertices.forEach(function(vertex)
var node = ;
node.id = vertex.id;
if (edgesForChildIndex[node.id] === undefined)
node.parent = '#';
else
node.parent = edgesForChildIndex[node.id][0].parentId;
node.text = (vertex.value === undefined || vertex.value === null) ? '' : vertex.value;
node.child = [];
if (edgesForParentIndex[node.id] === undefined)
node.child.push(cid: null, connectionText: "");
else
edgesForParentIndex[node.id].forEach(function(edge)
var text = (edge.value === undefined || edge.value === null) ? '' : edge.value;
node.child.push(cid: edge.childId, connectionText: text);
);
nodes.push(node);
);
return nodes;
【讨论】:
p13获取父子关系的资源
父子关系的资源我们怎么来获取一个公司有多个员工。employee不应该暴露成api,它应该体现出Company和Employee之间的关系。创建EmployeesController复数的形式。继承ControllerBase,并注入两个Repository如果注入为空则抛出异常来我们需要在... 查看详情
如何获取父子表(MS SQL Server/MSAccess)之间的参考信息?
】如何获取父子表(MSSQLServer/MSAccess)之间的参考信息?【英文标题】:Howtogetreferenceinformationbetweenparentandchildtables(MSSQLServer/MSAccess)?【发布时间】:2011-06-1406:28:09【问题描述】:是否可以通过某条记录获取子表是否引用了父表的... 查看详情
仅在父子实体具有 1 到 M 关系的核心数据中获取父实体的数据
】仅在父子实体具有1到M关系的核心数据中获取父实体的数据【英文标题】:FetchonlyParententity\'sdatainCoreDatawhereParentChildentityhas1toMrelationship【发布时间】:2018-04-0807:29:56【问题描述】:我有2个实体。国家和地区。国家与地区之间... 查看详情
对 system() 的调用不会在我的 Windows 进程之间创建父子关系
】对system()的调用不会在我的Windows进程之间创建父子关系【英文标题】:Acalltosystem()doesn\'tcreateaparent-childrelationbetweenmyprocessesinWindows【发布时间】:2012-04-2009:45:41【问题描述】:我正在使用Perl创建Windows服务。为此,我使用Win32::D... 查看详情
如何获取表之间的关系
】如何获取表之间的关系【英文标题】:Howtogetrelationshipbetweentables【发布时间】:2020-07-2912:58:23【问题描述】:您好,我正在为我的组织创建ER图。我怎样才能得到雪花表之间的关系谢谢【问题讨论】:你必须了解数据代表什么... 查看详情
p14获取父子关系的资源
通过CompanyId获取公司下面某一个员工运行测试这个employee的URI比较长返回结果companyId随便改一个这个时候返回了404companyId改回来。然后吧员工id随便改一个还是返回的是404结束 查看详情
进程之间的关系
...的时候、我们使用终端设备进行登录,但是由于终端设备连接的有限,因此登录的用户也就是有限的。随着位映射图形终端变得可用,开发出了窗口系统,它向用户提供了与主机系统进行交互的新方式。在这里、我简单介绍一下... 查看详情
vue父子组件兄弟组件之间的通信和访问
注意:比较复杂的嵌套类的通信问题都建议使用vuex一、父组件->子组件 (1)直接关系: 1.属性传值(props) 2. $children(数组) 3.$refs (2)跨多层关系: 1. provide/inject二、子组件-&g... 查看详情
从json数据中获取父子关系中所有子节点的总和
】从json数据中获取父子关系中所有子节点的总和【英文标题】:GetsumofAllChildreninparentandchildrelationfromjsondata【发布时间】:2021-12-2607:28:27【问题描述】:我有一个Json数据,它有父、子、孙等关系,就像一棵树他们每个人都有Openin... 查看详情
如何使用 Laravel 获取具有表之间关系的数据
】如何使用Laravel获取具有表之间关系的数据【英文标题】:HowgetdatahavingrelationshipsbetweentablesusingLaravel【发布时间】:2020-06-1309:51:01【问题描述】:我有一个带有Laravel的API,我决定使用表之间的关系,我已经在所有迁移中使用这... 查看详情
如何获取视图之间的mysql依赖关系?
】如何获取视图之间的mysql依赖关系?【英文标题】:Howtoobtainmysqldependenciesbetweenviews?【发布时间】:2013-01-3012:13:03【问题描述】:我有一个mysql数据库,有60多个视图,一些是辅助的,一些是最终的。它们之间存在依赖关系。这... 查看详情
vuejs - 在组件之间共享 websocket 连接
...17-08-1609:44:58【问题描述】:开始使用小型vuejs应用程序。如何在根组件中打开websocket连接并在其他组件中重用相同的连接?我希望组件能够通过同一连接发送和接收。这些组件将绑定到路由,因此根组件和为路由渲染的组件之间... 查看详情
用于获取存储在单个表中的 n 级父子关系的 Postgresql 查询
】用于获取存储在单个表中的n级父子关系的Postgresql查询【英文标题】:Postgresqlqueryforgettingn-levelparent-childrelationstoredinasingletable【发布时间】:2013-01-1713:34:33【问题描述】:我有一个表示父子关系的表。关系可以深入到n级。我使... 查看详情
如何从 Vapor 3 中的 JSON 响应中保存父子关系
】如何从Vapor3中的JSON响应中保存父子关系【英文标题】:HowtosaveParent-ChildrelationfromaJSONresponseinVapor3【发布时间】:2019-10-0919:31:41【问题描述】:我正在使用Vapor3开发一个RESTAPI。此API使用另一个API创建稍后将由应用程序使用的内... 查看详情
如何使用 Fluent API 映射这种冗余的父子关系
】如何使用FluentAPI映射这种冗余的父子关系【英文标题】:HowdoImapthisredundantparent-childrelationshipusingFluentAPI【发布时间】:2015-07-2710:49:01【问题描述】:关于如何双重映射这种父子关系的任何建议,其中父级具有正常的一对多关系... 查看详情
如何使用物料清单的父子记录创建简单的数据关系
】如何使用物料清单的父子记录创建简单的数据关系【英文标题】:HowtocreateasimpledatarelationshipusingparentchildrecordsforaBillofMaterials【发布时间】:2016-12-2120:29:00【问题描述】:我正在尝试开发一个简单的BOM(物料清单)管理器,它... 查看详情
父子链的外连接
】父子链的外连接【英文标题】:outerjoinforparentchildchain【发布时间】:2010-04-1516:29:30【问题描述】:考虑下表和关系:父母--1:Many--孩子--1:Many--子孩子父母可能有或很多没有孩子记录。子项总是有子项记录。我想编写一个查询来... 查看详情
创建骨骼的那些事-如何快速的创建骨骼的父子关系
我使用的2016的max版本。觉得这个版本的界面我还是很喜欢的。很好分类。 在3dmax中,我们在创建骨骼的父子关系时,在视图中选择时经常会很难选中要建立父子关系的两个骨骼,经常... 查看详情