上一节完成了架子的搭建以及节点的拖拽,这节完成节点菜单右键的操作
需求:
1、右键点击节点,弹出菜单,选中属性菜单项,右边再弹出菜单配置panel
2、点击其他节点或者界面空白处隐藏下拉菜单
效果图:
1、右键节点弹出菜单
点击属性节点弹出右边的panel
其中的核心代码:
第一步:注册右键菜单
node.append("circle")
.attr("r", nodeWidth)
.attr("fill", nodeColor)
.on("click", d => {
//左键盘点击 则隐藏右键菜单
this.vueMethods.hideNodeMenu&&this.vueMethods.hideNodeMenu();
//隐藏以前相应的选中状态
this.svgObj.selectAll("rect")
.attr("fill-opacity", 0)
.attr("stroke-opacity", 0);
//将当前节点设置为选中状态
window.d3.select("#"+"rect_"+d.id)
.attr("fill-opacity", 1)
.attr("stroke-opacity", 1);
console.log(d,"====");
})
.on("contextmenu", d => {
this._showNodeMenu(d);
})
;
// .attr("cx", 20)
// .attr("cy", 20);
node.append("text")
.attr("x", -nodeWidth/2)
.attr("y", "0.31em")
.text(nodeText)
.attr("fill", "#fff")
.attr("stroke", "white")
.attr("stroke-width", "0.5px")
.style('stroke',"#FFF")
.attr("stroke", "#fff")
.on("click", d => {
this.vueMethods.hideNodeMenu&&this.vueMethods.hideNodeMenu();
})
.on("contextmenu", d => {
this._showNodeMenu(d);
})
;
对圆圈和字都进行了菜单右键的注册,因为svg感觉没有事件冒泡这个说法,如果不是都注册可能导致点击没效果。
第二步:在vue的界面实现菜单
<div class="flow-node-menu" id="nodeMenu" v-show="nodeMenuFlag">
<div class="prop-menu-item" @click="propClick">
<div class="pull-left">
<i class=" flow go-end"></i>
</div>
<div class="pull-left item_label">
<label>属性</label>
</div>
</div>
<div class="prop-menu-item" @click="removeNodeClick">
<div class="pull-left">
<i class=" flow go-end"></i>
</div>
<div class="pull-left item_label">
<label>删除</label>
</div>
</div>
</div>
第三步:自然就是控制显示隐藏菜单的方法
//显示节点但右键菜单信息
showNodeMenu(x,elY,curNode){
this.curNode=curNode;
let {y}=GoingUtils.getElementPosition($("#flowLayout").get(0));
this.nodeMenuFlag=true;
if(x>0){
console.log(x,"====")
$("#nodeMenu").css("left",x+"px");
}
if(y>0){
console.log(y,"====")
$("#nodeMenu").css("top",elY-y+"px");
}
},
第四步:就是取消父界面的默认右键菜单操作,注册一个@contextmenu.prevent方法
<div slot="right" @contextmenu.prevent class="demo-split-pane" style="width: 100%;height: 100%;">
<div style="overflow: auto;width: 100%;height: calc(100% - 40px);position: relative;">
<div id="treeContainer" style="width: 100%;height: 100%;position: relative;margin: auto;">
</div>
</div>
</div>
第五步:准备右边的panel,我用的ivew的Drawer组件
<Drawer :inner="true" width="300" :transfer="false" :mask-closable="false" :mask="false" :closable="false" v-model="nodeProp">
<div class="drawer-header">
<div class="pull-left">
属性设置
</div>
<div class="pull-right" style="position: relative;top:-1px;color:#999;cursor: pointer;">
<i @click="closePropSetting" class=" goingicon go-doubleright"></i>
</div>
</div>
</Drawer>
最后自然就是添加panle的控制与显示了
//点击属性
propClick(){
this.nodeProp=true;
this.nodeMenuFlag=false;
},
基本思路和大概代码就是如此了。