<template lang='pug'>
|
.net
|
.arrow_box(:style="toolTipStyle")
|
p {{toolTipAddr}}
|
d3-network(
|
ref='net'
|
:startX="startX"
|
:net-nodes="nodes"
|
:net-links="links"
|
:options="options"
|
:selection="{nodes: nodeSelected, links: linksSelected}"
|
@drag-start='dragStart'
|
@node-click='nodeClick'
|
@node-hover='nodeHover'
|
@node-out='nodeOut'
|
)
|
</template>
|
|
<script>
|
import D3Network from "./vue-d3-network";
|
import RoleIcon from "./icons.js";
|
|
export default {
|
name: "SerfDiagram",
|
components: {
|
D3Network
|
},
|
props: {
|
agent: String,
|
members: Array,
|
sizeX: Number,
|
sizeY: Number,
|
startX: Number,
|
isShowHover: Boolean
|
},
|
data () {
|
return {
|
nodeSize: 20,
|
fontSize: 20,
|
canvas: false,
|
toolTipStyle: {
|
display: "none",
|
height: "30px",
|
width: "186px",
|
borderColor: "#ccc"
|
}
|
};
|
},
|
computed: {
|
nodes () {
|
let n = new Array();
|
this.members.forEach((v, i) => {
|
n.push({
|
id: i,
|
name: v.nodeName,
|
svgSym: RoleIcon[v.role],
|
_color:
|
v.role === "master"
|
? "orange"
|
: ""
|
|
});
|
});
|
|
return n;
|
},
|
links () {
|
let arr = new Array();
|
let dup = new Array(); // Deduplicate to ensure that two nodes have only one line
|
const count = this.members.length;
|
|
switch (count) {
|
case 0:
|
case 1:
|
break;
|
case 2:
|
arr = [{ sid: 0, tid: 1 }];
|
break;
|
case 3:
|
arr = [{ sid: 0, tid: 1 }, { sid: 1, tid: 2 }, { sid: 0, tid: 2 }];
|
break;
|
default:
|
for (let i = 0; i < count; i++) {
|
let loop = Math.round(Math.random() * 5 + 2); // At least 2 times
|
for (let j = 0; j < loop; j++) {
|
let target = Math.round(Math.random() * (count - 1));
|
if (target === i) {
|
// is me? skip
|
continue;
|
}
|
|
if (!dup["d" + target + i]) {
|
arr.push({ sid: i, tid: target });
|
dup["d" + i + target] = 1;
|
}
|
}
|
}
|
}
|
|
return arr;
|
},
|
options () {
|
return {
|
force: 3000,
|
nodeSize: this.nodeSize,
|
fontSize: this.fontSize,
|
nodeLabels: true,
|
canvas: this.canvas,
|
linkWidth: 0,
|
// size: {
|
// w: 745,
|
// h: 426
|
// }
|
size: {
|
w: this.sizeX || 445,
|
h: this.sizeY || 426
|
}
|
};
|
}
|
},
|
created () {
|
this.reset();
|
},
|
methods: {
|
nodeHover (event, node) {
|
console.log(node);
|
node._opacity = 1;
|
node._size = 28;
|
//let width = document.body.clientWidth;
|
if (this.isShowHover) {
|
this.toolTipStyle.display = "block";
|
this.toolTipStyle.top = node.y - 60 + "px";
|
this.toolTipStyle.left = node.x + "px";
|
console.log(this.members[node.id]);
|
let workName = '';
|
switch(this.members[node.id].workType){
|
case '01':
|
workName = '分析'
|
break;
|
case '02':
|
workName = '存储'
|
break;
|
case '03':
|
workName = '分析+存储'
|
break;
|
case '04':
|
workName = '应用'
|
break;
|
default:
|
return;
|
}
|
this.toolTipNode = this.members[node.id].nodeName;
|
this.toolTipAddr = `${this.members[node.id].Address}(${workName})`;
|
}
|
|
},
|
nodeOut (event, node) {
|
node._opacity = node.opacity;
|
node._size = node.size;
|
this.toolTipStyle.display = "none";
|
},
|
dragStart (event) {
|
if (event) {
|
this.movement = event.timeStamp;
|
}
|
},
|
nodeClick (event, node) {
|
// if (this.nodeSelected[node.id]) {
|
// this.unSelectNode(node.id)
|
// // is not nodeSelected
|
// } else {
|
// this.selectNode(node)
|
|
// }
|
// this.selectNodesLinks()
|
// this.$set(this.nodes, node.index, node)
|
console.log(event, node)
|
debugger
|
if (event.timeStamp - this.movement < 200) {
|
this.$emit("selected-node", event, this.members[node.id]);
|
}
|
},
|
reset () {
|
this.nodeSelected = {};
|
this.linksSelected = {};
|
(this.toolTipNode = ""), (this.toolTipAddr = ""), (this.movement = 0);
|
},
|
unSelectNode (nodeId) {
|
if (this.nodeSelected[nodeId]) {
|
delete this.nodeSelected[nodeId];
|
}
|
this.selectNodesLinks();
|
},
|
unSelectLink (linkId) {
|
if (this.linksSelected[linkId]) {
|
delete this.linksSelected[linkId];
|
}
|
},
|
selectNode (node) {
|
this.nodeSelected[node.id] = node;
|
},
|
selectLink (link) {
|
this.$set(this.linksSelected, link.id, link);
|
},
|
selectNodesLinks () {
|
for (let link of this.links) {
|
// node is nodeSelected
|
if (this.nodeSelected[link.sid] || this.nodeSelected[link.tid]) {
|
this.selectLink(link);
|
} else {
|
this.unSelectLink(link.id);
|
}
|
}
|
}
|
}
|
};
|
</script>
|
|
<style>
|
.net {
|
height: 100%;
|
margin: 0;
|
position: relative;
|
}
|
|
.node {
|
/* stroke: rgba(18, 120, 98, 0.7); */
|
stroke: rgba(76, 78, 78, 0.7);
|
stroke-width: 3px;
|
-webkit-transition: fill 0.5s ease;
|
transition: fill 0.5s ease;
|
/* fill: #dcfaf3; */
|
fill: #e3e4e4;
|
}
|
|
.node.selected {
|
stroke: #caa455;
|
}
|
|
.node.pinned {
|
stroke: rgba(190, 56, 93, 0.6);
|
}
|
|
.link {
|
stroke: rgba(18, 120, 98, 0.3);
|
}
|
|
.link,
|
.node {
|
stroke-linecap: round;
|
}
|
|
.link:hover,
|
.node:hover {
|
stroke: #df8108;
|
stroke-width: 1px;
|
cursor: pointer;
|
}
|
|
.link.selected {
|
stroke: rgba(202, 164, 85, 0.6);
|
}
|
|
.curve {
|
fill: none;
|
}
|
|
.link-label,
|
.node-label {
|
/* fill: #127862; */
|
fill: rgba(76, 78, 78, 0.7);
|
}
|
|
.link-label {
|
-webkit-transform: translateY(-0.5em);
|
transform: translateY(-0.5em);
|
text-anchor: middle;
|
}
|
|
.arrow_box {
|
position: absolute;
|
background: #fff;
|
/* border: 1px solid #127862; */
|
border: 1px solid #ccc;
|
font-size: 11px;
|
padding-left: 5px;
|
}
|
|
.arrow_box p {
|
height: 30px;
|
line-height: 30px;
|
width: 100%;
|
overflow: hidden;
|
}
|
.arrow_box:after,
|
.arrow_box:before {
|
right: 50%;
|
top: 100%;
|
border: solid transparent;
|
content: ' ';
|
height: 0;
|
width: 0;
|
position: absolute;
|
pointer-events: none;
|
}
|
|
.arrow_box:after {
|
border-color: rgba(136, 183, 213, 0);
|
border-right-color: #fff;
|
border-width: 5px;
|
margin-top: -5px;
|
transform: translateY(6px) rotateZ(-90deg);
|
}
|
.arrow_box:before {
|
border-color: rgba(194, 225, 245, 0);
|
border-right-color: #323333;
|
border-width: 5px;
|
margin-top: -5px;
|
}
|
.arrow_box:before {
|
border-color: rgba(194, 225, 245, 0);
|
border-right-color: #323333;
|
border-width: 5px;
|
margin-top: -5px;
|
transform: translateY(6px) rotateZ(-90deg);
|
}
|
</style>
|