vue中的template部分:
<div style="border-right:1px dashed #eee;">
<div id="node-popUp">
<p id="node-operation">nodep> <br>
<div style="margin: 10px;display:flex;align-items:center;">
<div style="flex:0 0 30%;margin-right:10px;text-align:right;">IDdiv>
<input disabled id="node-id" value="new value" class="ivu-input ivu-input-disabled" style="margin-right:20px;"/>
div>
<div style="margin: 10px;display:flex;align-items:center;">
<div style="flex:0 0 30%;margin-right:10px;text-align:right;">节点名称div>
<input id="node-label" value="new value" class="ivu-input" style="margin-right:20px;" />
div>
<div style="margin: 10px;display:flex;align-items:center;">
<div style="flex:0 0 30%;margin-right:10px;text-align:right;">节点类型div>
<select id="node-type" class="ivu-select-selection ivu-input" style="margin-right:20px;">
<option v-for="item in nodeType" :value="item.type" class="ivu-select-item">{{item.label}}option>
select>
div>
<div style="margin: 30px 20px;">
<input type="button" value="确定" id="node-saveButton" class="ivu-btn ivu-btn-primary" style="margin: 0 20px;" />
<input type="button" value="取消" id="node-cancelButton" class="ivu-btn ivu-btn-primary" style="margin: 0 10px;"/>
div>
div>
<div id="edge-popUp">
<p id="edge-operation">edgep>
<div style="margin: 10px;display:flex;align-items:center;">
<div style="flex:0 0 30%;margin-right:10px;text-align:right;">关系名称div>
<input id="edge-label" value="new value" class="ivu-input" style="margin-right:20px;" />
div>
<div style="margin: 10px;display:flex;align-items:center;">
<div style="flex:0 0 30%;margin-right:10px;text-align:right;">关系类型div>
<select id="edge-type" class="ivu-select-selection ivu-input" style="margin-right:20px;">
<option v-for="item in edgeType" :value="item.color" class="ivu-select-item">{{item.label}}option>
select>
div>
<div style="margin: 30px 20px;">
<input type="button" value="确定" id="edge-saveButton" class="ivu-btn ivu-btn-primary" style="margin: 0 20px;" />
<input type="button" value="取消" id="edge-cancelButton" class="ivu-btn ivu-btn-primary" style="margin: 0 10px;"/>
div>
div>
<div id="mynetwork">
div>
div>
vue 中的 javascript 部分:
export default {
data() {
return {
nodeType: [{//节点类型下拉选项
label: '蔬菜',
type: 'vegtables'
},{
label: '水果',
type: 'fruit''
}],
edgeType: [{
label: '资金',
color: '#0066CC'
},{
label: '关系',
color: '#9933cc'
},{
label: '物品',
color: '#663300'
}]
};
},
mounted () { //
this.draw();
},
methods: {
draw () {
let _this = this;
this.nodes = new DataSet(this.nodesList);
// create an array with edges
this.edges = new DataSet(this.edgesList);
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: this.nodes,
edges: this.edges
};
var options = {
autoResize: false,
interaction: {
hover: true
},
locale: 'cn',//工具栏显示中文
locales: {
cn: {//工具栏中文翻译
edit: '编辑',
del: '删除当前节点或关系',
back: '返回',
addNode: '添加节点',
addEdge: '添加连线',
editNode: '编辑节点',
editEdge: '编辑连线',
addDescription: '点击空白处可添加节点',
edgeDescription: '点击某个节点拖拽连线可连接另一个节点',
editEdgeDescription: '可拖拽连线改变关系',
createEdgeError: 'Cannot link edges to a cluster.',
deleteClusterError: 'Clusters cannot be deleted.',
editClusterError: 'Clusters cannot be edited.'
}
},
manipulation: {//工具栏
enabled: true,
initiallyActive: true, //直接显示工具栏
addNode: function(data, callback) { //添加节点
// filling in the popup DOM elements
document.getElementById('node-operation').innerHTML = "新增节点";
document.getElementById('node-id').value = data.id;
data.group = 'fruit';
editNode(data, clearNodePopUp, callback);
},
editNode: function(data, callback) { //编辑节点
// filling in the popup DOM elements
document.getElementById('node-operation').innerHTML = "编辑节点";
document.getElementById('node-id').value = data.id;
editNode(data, cancelNodeEdit, callback);
},
addEdge: function(data, callback) {
document.getElementById('edge-operation').innerHTML = "新增连线";
document.getElementById('edge-type').value = '#9933cc';
editEdgeWithoutDrag(data, callback);
},
editEdge:function(data, callback) {
document.getElementById('edge-popUp').style.display = 'block';
document.getElementById('edge-operation').innerHTML = "编辑连线";
editEdgeWithoutDrag(data, callback);
}
},
nodes: { //节点配置
borderWidth: 0, //节点边框的宽度,单位为px
color: { //字体配置
border: '#fff',
background: '#fff'
},
font: { //字体配置
color: '#333'
},
widthConstraint: { //节点名称宽度
maximum: 80
}
},
edges: { //连线配置
color: {
color: '#9933cc',
highlight: '#9933cc',
hover: '#9933cc'
},
widthConstraint: { //连接线信息宽度
maximum: 50
},
smooth: true, //是否显示方向箭头
arrows: { //箭头指向from节点
to: true
}
},
physics: {
maxVelocity: 4,
minVelocity: 0.62,
},
groups: {
vegetables: {
shape: 'image',
image: file,
},
fruit: {
shape: 'circularImage',
image: witness,
}
}
};
window.network = new Network(container, data, options);
network.on("dragEnd", e => { //拖拽完成
var _nodeId = e.nodes[0];
if (typeof _nodeId === 'undefined')
return;
_this.nodes.update({
id: _nodeId,
fixed: {
x: true,
y: true
}
});
});
network.on('dragStart', e => { //拖拽开始前
var _nodeId = e.nodes[0];
if (typeof _nodeId === 'undefined')
return;
_this.nodes.update({
id: _nodeId,
fixed: {
x: false,
y: false
}
});
});
network.on("click", params => { //点击画布
});
network.on("selectEdge", function (params) { //选择edge
console.log('selectEdge Event:', params);
});
network.on("hoverNode", params => { //hover节点时
document.getElementById("mynetwork").getElementsByTagName("canvas")[0].style.cursor = "pointer";
});
},
}
};
function editNode(data, cancelAction, callback) {
document.getElementById('node-label').value = data.label;
document.getElementById('node-type').value = data.group;
document.getElementById('node-saveButton').onclick = saveNodeData.bind(this, data, callback);
document.getElementById('node-cancelButton').onclick = cancelAction.bind(this, callback);
document.getElementById('node-popUp').style.display = 'block';
}
// Callback passed as parameter is ignored
function clearNodePopUp() {
document.getElementById('node-saveButton').onclick = null;
document.getElementById('node-cancelButton').onclick = null;
document.getElementById('node-popUp').style.display = 'none';
}
function cancelNodeEdit(callback) {
clearNodePopUp();
callback(null);
}
function saveNodeData(data, callback) {
data.label = document.getElementById('node-label').value;
data.group = document.getElementById('node-type').value;
clearNodePopUp();
callback(data);
}
function editEdgeWithoutDrag(data, callback) {
// filling in the popup DOM elements
document.getElementById('edge-label').value = data.label;
document.getElementById('edge-saveButton').onclick = saveEdgeData.bind(this, data, callback);
document.getElementById('edge-cancelButton').onclick = cancelEdgeEdit.bind(this, callback);
document.getElementById('edge-popUp').style.display = 'block';
}
function clearEdgePopUp() {
document.getElementById('edge-saveButton').onclick = null;
document.getElementById('edge-cancelButton').onclick = null;
document.getElementById('edge-popUp').style.display = 'none';
}
function cancelEdgeEdit(callback) {
clearEdgePopUp();
callback(null);
}
function saveEdgeData(data, callback) {
if (typeof data.to === 'object')
data.to = data.to.id
if (typeof data.from === 'object')
data.from = data.from.id
data.label = document.getElementById('edge-label').value;
data.color = document.getElementById('edge-type').value;
clearEdgePopUp();
callback(data);
}
vue中的style部分:
#mynetwork{
width: 100%;
height: 735px;
margin: 0;
border: 2px solid #fff;
color: #3693ff;
font: 14pt arial;
position:relative;
& .vis-manipulation{
display:flex !important;
position: absolute;
left: 65%;
top: 30px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
& .vis-label {
margin: 0 0 0 23px;
line-height: 25px;
}
& .vis-separator-line {
float: left;
display: inline-block;
width: 1px;
height: 21px;
background-color: #bdbdbd;
margin: 0 7px 0 15px;
}
& .vis-button{
font-family: verdana;
font-size: 1rem;
background-position: 0 0;
background-repeat: no-repeat;
height: 24px;
margin-left: 10px;
cursor: pointer;
padding: 0 8px 0 8px;
display:inline-flex;
background-size: contain;
}
& .vis-add{
background-image: url(./img/添加节点.svg);
}
& .vis-connect{
background-image: url(./img/添加连线.svg);
}
& .vis-edit{
background-image: url(./img/编辑.svg);
}
& .vis-delete{
background-image: url(./img/删除.svg);
}
& .vis-back{
background-image: url(./img/返回.svg);
}
}
& .vis-edit-mode{
position: absolute;
left:63%;
top: 15px;
height: 20px;
& .vis-edit{
background-image: url(./img/编辑.svg);
background-size: contain;
background-repeat: no-repeat;
width: 80px;
position: relative;
& .vis-label {
font-size:1rem;
cursor:pointer;
position: absolute;
bottom:0;
left: 25px;
}
}
}
& .vis-close{
position: absolute;
cursor: pointer;
right:10px;
top: 5px;
height: 20px;
width: 20px;
background-image: url(./img/cross.svg);
background-size: contain;
background-position: 0 0;
background-repeat: no-repeat;
}
}
#operation {
font-size:28px;
}
#node-popUp {
display:none;
position: absolute;
top: 90px;
right: 10px;
z-index: 299;
width: 400px;
height: 300px;
text-align: center;
border: 1px solid #eee;
box-shadow: 0px -5px 5px rgba(0, 0, 0, 0.14);
}
#edge-popUp {
display:none;
position: absolute;
top: 90px;
right: 10px;
z-index: 299;
width: 400px;
height: 250px;
text-align: center;
border: 1px solid #eee;
box-shadow: 0px -5px 5px rgba(0, 0, 0, 0.14);
}
#node-operation, #edge-operation{
padding:10px;
border-bottom: 1px solid #eee;
}