如何绘制多堆栈,多对多关系图,如附图所示,使用JavaScript?
How to draw a multi stack, many to many relationship diagram, something like in the attached picture, using JavaScript?
我想用JavaScript画一个关系图(类似上图)。我尝试了很多 js 库,如 D3、GoJs、JsPlumb 等,但没有一个能满足我的要求。请在下方找到附加要求。
- 框(例如业务架构 > 流程 > 解决投诉)最多可以有四个内部级别。
- 任何框都可以与任何框连接(内部 - 在组内和外部 - 与其他组中的节点)
- 关系可以是单向和双向(单向箭头和双向箭头)并且应该有关系类型(例如过程)。
- 每个框(所有级别)都应该有四个可点击的热点
- 可以保存为模板以供日后修改
- 数据源是 JSON
此解决方案创建于 GoJS。
这是结果。抱歉,我不想输入您屏幕截图中的所有数据,所以我只输入了前两组。而且我也没有很好地设计样式。
这是完整的页面,包括 JSON 格式的图表模型数据:
<!DOCTYPE html>
<html>
<head>
<title>Simple Nested Relationships in GoJS</title>
<!-- Copyright 1998-2017 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="go.js"></script>
<script id="code">
function init() {
var $ = go.GraphObject.make;
myDiagram =
$(go.Diagram, "myDiagramDiv",
{
initialContentAlignment: go.Spot.Center,
"undoManager.isEnabled": true
});
function makePort(id, spot) {
return $(go.Shape,
{
fill: "transparent", strokeWidth: 0,
width: 10, height: 10,
alignment: spot, alignmentFocus: spot,
portId: id,
fromLinkable: true, toLinkable: true, cursor: "pointer"
});
}
myDiagram.nodeTemplate =
$(go.Node, "Spot",
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Panel, "Auto",
$(go.Shape, "RoundedRectangle",
{ fill: "white" },
new go.Binding("fill", "color"),
new go.Binding("figure"),
new go.Binding("angle", "figure", function(f) { return f === "Hexagon" ? 90 : 0; })),
$(go.TextBlock,
{ margin: 4, editable: true, maxSize: new go.Size(150, NaN), textAlign: "center" },
new go.Binding("text").makeTwoWay())
),
makePort("T", go.Spot.Top),
makePort("R", go.Spot.Right),
makePort("B", go.Spot.Bottom),
makePort("L", go.Spot.Left)
);
myDiagram.groupTemplate =
$(go.Group, "Spot",
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Panel, "Auto",
$(go.Shape,
{ fill: "whitesmoke" },
new go.Binding("fill", "color"),
new go.Binding("stroke", "color", go.Brush.darken)),
$(go.Panel, "Vertical",
$(go.TextBlock,
{ margin: 4, editable: true },
new go.Binding("text").makeTwoWay()),
$(go.Placeholder, { padding: 10 })
)
),
makePort("T", go.Spot.Top),
makePort("R", go.Spot.Right),
makePort("B", go.Spot.Bottom),
makePort("L", go.Spot.Left)
);
myDiagram.linkTemplate =
$(go.Link,
$(go.Shape, { strokeWidth: 2 }),
$(go.Shape, { fromArrow: "Standard", visible: false },
new go.Binding("visible", "from")),
$(go.Shape, { toArrow: "Standard" }),
$(go.TextBlock,
{ font: "11px sans-serif", editable: true },
new go.Binding("text").makeTwoWay())
);
myDiagram.model = go.Model.fromJson(
'{ "class": "go.GraphLinksModel",\
"linkFromPortIdProperty": "fp",\
"linkToPortIdProperty": "tp",\
"nodeDataArray": [\
{ "key": 1, "text": "Strategic Planning", "color": "lightgreen", "isGroup": true, "loc": "10.5 22" },\
{ "key": 11, "text": "Business Policy", "color": "rgba(182, 255, 180, 1)", "isGroup": true, "group": 1, "loc": "21 116" },\
{ "key": 111, "text": "Adhere to FSA Guidelines", "color": "lightgreen", "figure": "Hexagon", "group": 11, "loc": "31 126" },\
{ "key": 12, "text": "Strategy", "color": "rgba(182, 255, 180, 1)", "isGroup": true, "group": 1, "loc": "162 55" },\
{ "key": 121, "text": "Adopt Customer\nComplaints Process", "color": "lightskyblue", "group": 12, "loc": "172 65" },\
{ "key": 122, "text": "Mission and\nVision", "color": "plum", "group": 12, "loc": "274 136" },\
{ "key": 123, "text": "Improve Customer Satisfaction", "color": "lightskyblue", "group": 12, "loc": "177 206" },\
{ "key": 124, "text": "Decisions made wlil Maximize Benefit to the Enterprise", "color": "lightskyblue", "group": 12, "loc": "304 203" },\
{ "key": 2, "text": "Business Architecture", "color": "silver", "isGroup": true, "loc": "503 21" },\
{ "key": 21, "text": "Process", "color": "lightgray", "isGroup": true, "group": 2, "loc": "514 54" },\
{ "key": 211, "text": "Complaints\n Handling", "color": "lightgreen", "figure":"Hexagon", "group": 21, "loc": "546 35" },\
{ "key": 212, "text": "Resolve \nComplaint", "color": "lightskyblue", "group": 21, "loc": "679 64" },\
{ "key": 213, "text": "Complaints\n Handling", "color": "lightskyblue", "group": 21, "loc": "550 145" },\
{ "key": 22, "text": "Organization", "color": "lightgray", "isGroup": true, "group": 2, "loc": "842 55" },\
{ "key": 221, "text": "Complaints \nCall Handler", "color": "lightskyblue", "group": 22, "loc": "852 65.6" },\
{ "key": -18, "text": "Complaints \nClient", "color": "lightskyblue", "group": 22, "loc": "854 142" },\
{ "key": -19, "text": "Complaints \nManager", "color": "lightskyblue", "group": 22, "loc": "852 225" },\
{ "key": 23, "text": "Business Service", "color": "lightgray", "isGroup": true, "group": 2, "loc": "514 217" },\
{ "key": 231, "text": "Manage \nComplaints", "color": "lightskyblue", "group": 23, "loc": "550 247" }\
],\
"linkDataArray": [\
{ "from": 111, "to": 123, "fp": "R", "tp": "L" },\
{ "from": 121, "to": 123, "fp": "B", "tp": "T", "text": "Process" },\
{ "from": 121, "to": 122, "fp": "B", "tp": "T", "text": "Process" },\
{ "from": 121, "to": 211, "fp": "R", "tp": "L", "text": "Process" },\
{ "from": 121, "to": 231, "fp": "R", "tp": "L", "text": "Process" },\
{ "from": 211, "to": 213, "fp": "B", "tp": "T", "text": "Process type:\nProcess" },\
{ "from": 231, "to": 213, "fp": "T", "tp": "B", "text": "Process" },\
{ "from": 231, "to": 212, "fp": "T", "tp": "B" },\
{ "from": 212, "to": -19, "fp": "B", "tp": "L", "text": "Process" },\
{ "from": 212, "to": -18, "fp": "B", "tp": "L", "text": "Process" },\
{ "from": 212, "to": 221, "fp": "R", "tp": "L", "text": "Process" }\
]\
}'
);
}
</script>
</head>
<body onload="init()">
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
</body>
</html>
我想用JavaScript画一个关系图(类似上图)。我尝试了很多 js 库,如 D3、GoJs、JsPlumb 等,但没有一个能满足我的要求。请在下方找到附加要求。
- 框(例如业务架构 > 流程 > 解决投诉)最多可以有四个内部级别。
- 任何框都可以与任何框连接(内部 - 在组内和外部 - 与其他组中的节点)
- 关系可以是单向和双向(单向箭头和双向箭头)并且应该有关系类型(例如过程)。
- 每个框(所有级别)都应该有四个可点击的热点
- 可以保存为模板以供日后修改
- 数据源是 JSON
此解决方案创建于 GoJS。
这是结果。抱歉,我不想输入您屏幕截图中的所有数据,所以我只输入了前两组。而且我也没有很好地设计样式。
这是完整的页面,包括 JSON 格式的图表模型数据:
<!DOCTYPE html>
<html>
<head>
<title>Simple Nested Relationships in GoJS</title>
<!-- Copyright 1998-2017 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="go.js"></script>
<script id="code">
function init() {
var $ = go.GraphObject.make;
myDiagram =
$(go.Diagram, "myDiagramDiv",
{
initialContentAlignment: go.Spot.Center,
"undoManager.isEnabled": true
});
function makePort(id, spot) {
return $(go.Shape,
{
fill: "transparent", strokeWidth: 0,
width: 10, height: 10,
alignment: spot, alignmentFocus: spot,
portId: id,
fromLinkable: true, toLinkable: true, cursor: "pointer"
});
}
myDiagram.nodeTemplate =
$(go.Node, "Spot",
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Panel, "Auto",
$(go.Shape, "RoundedRectangle",
{ fill: "white" },
new go.Binding("fill", "color"),
new go.Binding("figure"),
new go.Binding("angle", "figure", function(f) { return f === "Hexagon" ? 90 : 0; })),
$(go.TextBlock,
{ margin: 4, editable: true, maxSize: new go.Size(150, NaN), textAlign: "center" },
new go.Binding("text").makeTwoWay())
),
makePort("T", go.Spot.Top),
makePort("R", go.Spot.Right),
makePort("B", go.Spot.Bottom),
makePort("L", go.Spot.Left)
);
myDiagram.groupTemplate =
$(go.Group, "Spot",
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Panel, "Auto",
$(go.Shape,
{ fill: "whitesmoke" },
new go.Binding("fill", "color"),
new go.Binding("stroke", "color", go.Brush.darken)),
$(go.Panel, "Vertical",
$(go.TextBlock,
{ margin: 4, editable: true },
new go.Binding("text").makeTwoWay()),
$(go.Placeholder, { padding: 10 })
)
),
makePort("T", go.Spot.Top),
makePort("R", go.Spot.Right),
makePort("B", go.Spot.Bottom),
makePort("L", go.Spot.Left)
);
myDiagram.linkTemplate =
$(go.Link,
$(go.Shape, { strokeWidth: 2 }),
$(go.Shape, { fromArrow: "Standard", visible: false },
new go.Binding("visible", "from")),
$(go.Shape, { toArrow: "Standard" }),
$(go.TextBlock,
{ font: "11px sans-serif", editable: true },
new go.Binding("text").makeTwoWay())
);
myDiagram.model = go.Model.fromJson(
'{ "class": "go.GraphLinksModel",\
"linkFromPortIdProperty": "fp",\
"linkToPortIdProperty": "tp",\
"nodeDataArray": [\
{ "key": 1, "text": "Strategic Planning", "color": "lightgreen", "isGroup": true, "loc": "10.5 22" },\
{ "key": 11, "text": "Business Policy", "color": "rgba(182, 255, 180, 1)", "isGroup": true, "group": 1, "loc": "21 116" },\
{ "key": 111, "text": "Adhere to FSA Guidelines", "color": "lightgreen", "figure": "Hexagon", "group": 11, "loc": "31 126" },\
{ "key": 12, "text": "Strategy", "color": "rgba(182, 255, 180, 1)", "isGroup": true, "group": 1, "loc": "162 55" },\
{ "key": 121, "text": "Adopt Customer\nComplaints Process", "color": "lightskyblue", "group": 12, "loc": "172 65" },\
{ "key": 122, "text": "Mission and\nVision", "color": "plum", "group": 12, "loc": "274 136" },\
{ "key": 123, "text": "Improve Customer Satisfaction", "color": "lightskyblue", "group": 12, "loc": "177 206" },\
{ "key": 124, "text": "Decisions made wlil Maximize Benefit to the Enterprise", "color": "lightskyblue", "group": 12, "loc": "304 203" },\
{ "key": 2, "text": "Business Architecture", "color": "silver", "isGroup": true, "loc": "503 21" },\
{ "key": 21, "text": "Process", "color": "lightgray", "isGroup": true, "group": 2, "loc": "514 54" },\
{ "key": 211, "text": "Complaints\n Handling", "color": "lightgreen", "figure":"Hexagon", "group": 21, "loc": "546 35" },\
{ "key": 212, "text": "Resolve \nComplaint", "color": "lightskyblue", "group": 21, "loc": "679 64" },\
{ "key": 213, "text": "Complaints\n Handling", "color": "lightskyblue", "group": 21, "loc": "550 145" },\
{ "key": 22, "text": "Organization", "color": "lightgray", "isGroup": true, "group": 2, "loc": "842 55" },\
{ "key": 221, "text": "Complaints \nCall Handler", "color": "lightskyblue", "group": 22, "loc": "852 65.6" },\
{ "key": -18, "text": "Complaints \nClient", "color": "lightskyblue", "group": 22, "loc": "854 142" },\
{ "key": -19, "text": "Complaints \nManager", "color": "lightskyblue", "group": 22, "loc": "852 225" },\
{ "key": 23, "text": "Business Service", "color": "lightgray", "isGroup": true, "group": 2, "loc": "514 217" },\
{ "key": 231, "text": "Manage \nComplaints", "color": "lightskyblue", "group": 23, "loc": "550 247" }\
],\
"linkDataArray": [\
{ "from": 111, "to": 123, "fp": "R", "tp": "L" },\
{ "from": 121, "to": 123, "fp": "B", "tp": "T", "text": "Process" },\
{ "from": 121, "to": 122, "fp": "B", "tp": "T", "text": "Process" },\
{ "from": 121, "to": 211, "fp": "R", "tp": "L", "text": "Process" },\
{ "from": 121, "to": 231, "fp": "R", "tp": "L", "text": "Process" },\
{ "from": 211, "to": 213, "fp": "B", "tp": "T", "text": "Process type:\nProcess" },\
{ "from": 231, "to": 213, "fp": "T", "tp": "B", "text": "Process" },\
{ "from": 231, "to": 212, "fp": "T", "tp": "B" },\
{ "from": 212, "to": -19, "fp": "B", "tp": "L", "text": "Process" },\
{ "from": 212, "to": -18, "fp": "B", "tp": "L", "text": "Process" },\
{ "from": 212, "to": 221, "fp": "R", "tp": "L", "text": "Process" }\
]\
}'
);
}
</script>
</head>
<body onload="init()">
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
</body>
</html>