系统不识别美元符号,emit和Message前需要加$符号
html部分


<div class=“close-it” @click=“closePage”>×

<div class=“save-it” @click=“savePage”>保存


<Select v-if=“clickedNode && !writeNewNode” v-model=“nodeName” placeholder=“请选择节点名称” style=“width:150px;margin-left:90px;” @on-change=“getEquipmentNum”>
{{item.name}}

<Button v-if=“clickedNode” type=“primary” @click.native=“toWriteNewNode” style=“margin-left:10px;”>{{writeNewNodeText}}
<Button v-if=“clickedNode” type=“primary” @click.native=“confirmNodeName” style=“margin-left:10px;”>确定
<Button v-if=“clickedNode” type=“primary” @click.native=“clickedNode = false” style=“margin-left:10px;”>取消

        <Select v-if="alteringNode" v-model="alterText" placeholder="请选择节点名称" style="width: 150px;margin-left:10px;" @on-change="getEquipmentNum1"><Option v-for="item in equipmentList" :key="item.num" :value="item.name">{{item.name}}</Option></Select><Input v-if="alteringNode" v-model="nodeWidth" placeholder="请输入节点宽度" style="width: 150px;margin-left:10px;" /><Input v-if="alteringNode" v-model="nodeHeight" placeholder="请输入节点高度" style="width: 150px;margin-left:10px;" /><Button v-if="alteringNode" type="primary" @click.native="confirmAlterText" style="margin-left:10px;">确定</Button><Button v-if="alteringNode" type="primary" @click.native="cancelAltering" style="margin-left:10px;">取消</Button></div><div class="draw-title"></div><div class="draw-content"><div class="draw-content-tool"><div class="draw-content-tool-node" @click="clickNode">节点</div><div class="draw-content-tool-link" @click="clickLink">连接</div><div class="draw-content-tool-node" @click="deleteNode">删除节点</div><div class="draw-content-tool-node" @click="alterNode">修改节点</div><div class="draw-content-tool-node" @click="deleteLink">删除连接</div></div><canvas id="draw-topo-canvas" class="draw-content-canvas" @click="drawInCanvas" width="944" height="728"></canvas><div class="draw-topo-description"><p v-for="(item,index) in testMessages" :key="index" :style="{color:randomColor()}">{{item.text}}</p></div></div>
</div>

js部分
import axios from “@/libs/api.request”;
export default {
name: ‘drawTopo’,
props: {
companyCode:String
},
data() {
return {
equipmentList:[],
nodes:[],
links:[],
writeNewNode:false,//输入节点和选择节点之间切换的flag
writeNewNodeText:‘输入新节点’,//切换输入和选择节点button的文字
startNode:’’,//连线开始node
endNode:’’,//连线结束node
clickedNode:false,
clickedLink:false,
nodeName:’’,
equipmentNum:’’,
nodeWidth:’’,
nodeHeight:’’,
confirmedNodeName:’’,
stage:{},
scene:{},
calcNum:-1,//nodes中item的index值
deletingNode:false,
testMessages:[],
colors:[‘red’,‘orange’,‘green’,‘blue’,‘purple’,’#000’,’#2fdc74’,’#e0290c’,’#09aeec’,’#33022b’,’#150263’,‘red’,‘orange’,‘green’,‘blue’,‘purple’,’#000’,’#2fdc74’,’#e0290c’,’#09aeec’,’#33022b’,’#150263’],
alterText:’’,
alteringNode:false,
confirmedAlteringText:false,
topoId:’’
}
},
methods: {
toWriteNewNode(){
this.writeNewNode = !this.writeNewNode
if(this.writeNewNodeText == ‘输入新节点’){
this.writeNewNodeText = ‘选择新节点’
}else{
this.writeNewNodeText = ‘输入新节点’
this.equipmentNum = ‘’
}
},
getEquipmentNum(){
this.equipmentNum = this.equipmentList.find(item =>{
return item.name == this.nodeName
}).num
},
getEquipmentNum1(){
this.equipmentNum = this.equipmentList.find(item =>{
return item.name == this.alterText
}).num
},
randomColor(){
let index = Math.floor(22Math.random())
return this.colors[index]
},
closePage(){
this.emit(‘cancel’,false)
},
savePage(){
this.emit(‘save’,this.nodes,this.links,this.companyCode,this.topoId)
},
node(x,y,name,width,height,statu){
let node = new JTopo.Node(name);
node.setLocation(x, y);
node.setSize(width,height);
if(statu){
node.fillColor = ‘45, 140, 240’
}else{
node.fillColor = ‘204,204,204’
}
node.text = name; // 文字
node.fontColor = ‘0,0,0’
node.textPosition = ‘Middle_Center’;// 文字居中
node.font = “16px Consolas”;
node.textOffsetY = -8;
node.index = this.calcNum;
node.num = this.equipmentNum;
this.scene.add(node);
this.nodes.push(node);
this.nodeName = ‘’;
this.confirmedNodeName = ‘’;
let obj = {
text: ‘节点创建成功,请在工具栏选择要进行的操作’
};
this.testMessages.push(obj);
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
};
return node;
},
//定义连线函数
linkNode(nodeA, nodeZ,color){
console.log(‘linkNode’)
var link = new JTopo.Link(nodeA, nodeZ);
link.lineWidth = 3;
link.strokeColor = color;
link.arrowsRadius = 10;
this.scene.add(link);
let obj = {
from:nodeA.index,
to:nodeZ.index
}
this.links.push(obj)
console.log(this.links)
return link;
},
clickNode(){
this.deletingNode = false
this.clickedNode = true
this.alteringNode = false
this.clickedLink = false
this.deletingLink = false
this.confirmedAlteringText == false
this.confirmedNodeName = ‘’
this.nodeWidth = ‘’
this.nodeHeight = ‘’
this.equipmentNum = ‘’
let obj = {
text:‘开始绘制节点,请先填写节点名称,宽度,高度’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
},
clickLink(){
this.deletingNode = false
this.clickedNode = false
this.alteringNode = false
this.deletingLink = false
this.clickedLink = true
this.confirmedAlteringText == false
this.startNode = ‘’
this.endNode = ‘’
this.confirmedNodeName = ‘’
this.Message.success(‘请先选择初始节点’)
let obj = {
text:‘连线操作开始,请先选择初始节点’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
},
//删除节点
deleteNode(){
this.deletingNode = true
this.alteringNode = false
this.clickedNode = false
this.clickedLink = false
this.deletingLink = false
this.confirmedAlteringText == false
this.nodeName = ‘’
this.confirmedNodeName = ‘’
this.nodeWidth = ‘’
this.nodeHeight = ‘’
this.Message.success(‘开启删除节点模式,点击节点删除节点’)
let obj = {
text:‘开启删除节点模式,点击节点删除节点’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
},
deleteLink(){
this.deletingLink = true
this.deletingNode = false
this.alteringNode = false
this.clickedNode = false
this.clickedLink = false
this.confirmedAlteringText == false
this.nodeName = ‘’
this.confirmedNodeName = ‘’
this.nodeWidth = ‘’
this.nodeHeight = ‘’
this.Message.success(‘开启删除连接模式,点击连接删除连接’)
let obj = {
text:‘开启删除连接模式,点击连接删除连接’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
},
//修改节点文字
alterNode(){
this.alteringNode = true
this.deletingNode = false
this.clickedNode = false
this.clickedLink = false
this.deletingLink = false
this.confirmedAlteringText == false
this.nodeName = ‘’
this.confirmedNodeName = ‘’
this.nodeWidth = ‘’
this.nodeHeight = ‘’
let obj = {
text:‘开启修改节点文字模式,请输入节点名,然后点确定’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
},
confirmNodeName(){
if(this.nodeName == ‘’){
this.Message.warning(‘请输入节点名称’)
let obj = {
text:‘请输入节点名称’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
return
}
let obj = {
text:‘节点信息填写完成,请在画布上任意位置点击鼠标创建节点’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
this.clickedNode = false
this.startNode = ‘’
this.endNode = ‘’
this.confirmedNodeName = this.nodeName
if(this.confirmedNodeName.length <= 4){
this.nodeWidth = 80
this.nodeHeight = 40
}else{
this.nodeWidth = 20
(this.confirmedNodeName.length)
this.nodeHeight = 40
}
},
confirmAlterText(){
let reg = /1\d*(美元符号)/
if(this.nodeWidth != ‘’){
if(!reg.test(this.nodeWidth)){
this.Message.warning(‘宽度请输入正整数’)
return
}
}
if(this.nodeHeight != ‘’){
if(!reg.test(this.nodeHeight)){
this.Message.warning(‘高度请输入正整数’)
return
}
}
if(this.alterText != ‘’){
this.confirmedAlteringText = true
this.alteringNode = false
let obj = {
text:‘节点名填写完成,请点击节点替换节点名’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
}else{
let obj = {
text:‘节点名未填写’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
}
},
cancelAltering(){
this.alteringNode = false
this.confirmedAlteringText = false
},
drawInCanvas(e){
let x,y
if(this.clickedNode == false && this.clickedLink == false && this.confirmedNodeName != ‘’ && this.deletingNode == false){
x = e.x - 80
y = e.y - 40
this.calcNum = this.calcNum + 1
this.node(x,y,this.confirmedNodeName,Number(this.nodeWidth),Number(this.nodeHeight),true)
}else if(this.clickedLink == true){
x = e.x - 80
y = e.y - 40
if(this.nodes.length > 1){
for(let i in this.nodes){
if(y>=this.nodes[i].y && y<=this.nodes[i].y + this.nodes[i].height && x>=this.nodes[i].x && x<=this.nodes[i].x + this.nodes[i].width){
if(this.startNode == ‘’ && this.endNode == ‘’){
this.startNode = this.nodes[i]
this.endNode = ‘’
this.Message.success(‘初始节点选择成功,请选择结束节点’)
let obj = {
text:‘初始节点选择成功,请选择结束节点’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
}else if(this.startNode != ‘’ && this.endNode == ‘’){
if(this.startNode.index == this.nodes[i].index){
let obj = {
text:‘不可连接同一个节点,请选择结束节点’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
return
}
this.endNode = this.nodes[i]
this.linkNode(this.startNode,this.endNode,’#000’)
this.Message.success(‘连线成功,请选择初始节点’)
let obj = {
text:‘连线成功,请选择初始节点’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
}else{
this.startNode = this.nodes[i]
this.endNode = ‘’
this.Message.success(‘初始节点选择成功,请选择结束节点’)
let obj = {
text:‘初始节点选择成功,请选择结束节点’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
}
}
}
}else{
let obj = {
text:‘节点数不足2个,不支持连线操作’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
}
}else if(this.deletingNode == true){
x = e.x - 80
y = e.y - 40
if(this.nodes.length > 0){
console.log(this.nodes)
for(let i in this.nodes){
if(y>=this.nodes[i].y && y<=this.nodes[i].y + this.nodes[i].height && x>=this.nodes[i].x && x<=this.nodes[i].x + this.nodes[i].width){
let obj = this.nodes[i]
let index = this.nodes[i].index
for(let z=0;z<this.links.length;z++){
let item = this.links[z]
if(item.from == index || item.to == index){
this.links.splice(z–,1)
}
}
console.log(this.links)
this.nodes.splice(i,1)
this.scene.remove(obj)
this.Message.success(‘节点删除成功,请重新点击删除节点’)
let obj1 = {
text:‘节点删除成功,请重新点击删除节点’
}
this.testMessages.push(obj1)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
this.deletingNode = false
}
}
}
}else if(this.confirmedAlteringText == true && this.deletingLink == false){
x = e.x - 80
y = e.y - 40
if(this.nodes.length > 0){
console.log(this.nodes)
for(let i in this.nodes){
if(y>=this.nodes[i].y && y<=this.nodes[i].y + this.nodes[i].height && x>=this.nodes[i].x && x<=this.nodes[i].x + this.nodes[i].width){
if(this.alterText != ‘’){
this.nodes[i].text = this.alterText
this.nodes[i].num = this.equipmentNum
this.alterText = ‘’
if(this.nodeWidth != ‘’){
this.nodes[i].width = Number(this.nodeWidth)
this.(美元符号)nextTick(()=>{
this.nodeWidth = ‘’
})
}
if(this.nodeHeight != ‘’){
this.nodes[i].height = Number(this.nodeHeight)
this.(美元符号)nextTick(()=>{
this.nodeHeight = ‘’
})
}
}else{
this.Message.warning(‘请先填写要替换的节点名’)
return
}
}
}
}
let obj = {
text:‘节点名称已修改’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
this.alteringNode = false
this.confirmedAlteringText == false
}else if(this.deletingLink == true){
let link = this.scene.selectedElements
if(link!= null && link[0].elementType == “link”){
let from = link[0].nodeA.index
let to = link[0].nodeZ.index
for(let i in this.links){
if(this.links[i].from == from && this.links[i].to == to){
this.links.splice(i,1)
}
}
this.scene.remove(link[0]);//remove的是link[0]对象,不是link…
this.deletingLink = false
let obj = {
text:‘连接删除成功,请选择工具栏中的功能继续操作’
}
this.testMessages.push(obj)
if(this.testMessages.length >= 10){
this.testMessages.splice(0,1)
}
}
}
}
},
mounted() {
this.nodes = []
this.links = []
axios.request({
url: “获取要绘制的节点列表” ,
method: “get”
}).then(res =>{
if(res.code == 200){
this.equipmentList = res.data
}
})

    axios.request({url: "获取之前保存的数据列表",method: "get"}).then(res =>{if(res.topology != ''){this.topoId = res.topology.idif(res.topology.nodes.length > 0){for(let a=0;a<res.topology.nodes.length;a++){this.nodes.push(res.topology.nodes[a])}}if(res.topology.links.length > 0){for(let b=0;b<res.topology.links.length;b++){this.links.push(res.topology.links[b])}}}this.(美元符号)nextTick(()=>{var canvas = document.getElementById('draw-topo-canvas');this.stage = new JTopo.Stage(canvas);this.scene = new JTopo.Scene();this.scene.mode = 'edit';this.stage.add(this.scene);if(this.nodes.length != 0){let initNodeLength = this.nodes.lengthfor(let i=0;i<initNodeLength;i++){this.calcNum = this.nodes[i].indexthis.equipmentNum = this.nodes[i].numthis.node(Number(this.nodes[i].x),Number(this.nodes[i].y),this.nodes[i].text,Number(this.nodes[i].width),Number(this.nodes[i].height),this.nodes[i].statu)}for(let z=0;z<initNodeLength;z++){this.nodes.splice(0,1)}if(this.links.length != 0){let linkLength = this.links.lengthfor(let j=0;j<linkLength;j++){let startNode = this.nodes.find(item =>{return item.index == this.links[j].from})let endNode = this.nodes.find(item =>{return item.index == this.links[j].to})this.linkNode(startNode,endNode,'#000')}for(let x=0;x<linkLength;x++){this.links.splice(0,1)}}}this.testMessages = [{text:'页面加载成功'},{text:'请先选择节点'},]})})
},
beforeDestroy() {
}

}
页面内样式
.input-condition{
position:fixed;
z-index:111;
width:100vw;
height:40px;
display: flex;
align-items: center;
justify-content: flex-start;
background-color:#fff;
}
.close-it{
position:fixed;
z-index:11;
width:40px;
height:40px;
font-size:40px;
color:#fff;
font-weight: bold;
cursor:pointer;
right: 0;
top:0;
display: flex;
justify-content: center;
align-items: center;
}
.save-it{
position:fixed;
z-index:11;
width:80px;
height:40px;
font-size:20px;
color:#fff;
font-weight: bold;
cursor:pointer;
right: 40px;
top:0;
display: flex;
justify-content: center;
align-items: center;
}
.draw-title{
width:100%;
height:40px;
background-color: rgb(45, 140, 240);
}
.draw-content{
width:100%;
height:calc(100vh - 40px);
display: flex;
background-color: rgb(45, 140, 240);
}
.draw-content-tool{
width:80px;
height:calc(100vh - 40px);
background-color: rgb(45, 140, 240);
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.draw-content-canvas{
position:absolute;
top:40px;
left:80px;
background-color: #fff;
text-align: center;
width:944px;
height:728px;
}
.draw-topo-description{
width:calc(100vw - 1024px);
height:calc(100vh - 40px);
background-color:#ccc;
position:absolute;
top:40px;
left:1024px;
z-index:11;
padding:20px;
line-height: 26px;
font-size:15px;
}
.draw-content-tool-node, .draw-content-tool-link{
width:100%;
height:80px;
line-height: 80px;
color: #fff;
text-align: center;
cursor: pointer;
}
公共样式
.ivu-message{
top:50px!important;
z-index:999999999999999;
}


  1. 1-9 ↩︎

手绘topo图组件 vue + element-ui + jtopo相关推荐

  1. Vue Element UI 表格组件 利用插槽实现按下按钮后获得本行数据(内容)

    Vue Element UI 表格组件 利用插槽实现按下按钮后获得本行数据(内容) 能够解决的问题 需要在表格中添加一个类似修改或编辑的按钮,按下按钮,弹出的窗口需要本行的渲染数据 需要向服务端提交一 ...

  2. 【前端】Vue+Element UI案例:通用后台管理系统-代码总结(已开源)

    文章目录 前言 项目文件目录 api mockServe home.js permission.js index.js mock.js user.js assert components Common ...

  3. 基于vue(element ui) + ssm + shiro 的权限框架

    zhcc 基于vue(element ui) + ssm + shiro 的权限框架 引言 心声 现在的Java世界,各种资源很丰富,不得不说,从分布式,服务化,orm,再到前端控制,权限等等玲琅满目 ...

  4. 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改、Pagination分页、搜索框

    文章目录 目标 代码 0.结构 1.按钮-删除 2.按钮-编辑 3.debug 4.样式 5.分页Pagination:功能 6.分页Pagination:样式 7.搜索框:功能 8.搜索框:样式 总 ...

  5. 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出

    文章目录 目标 代码 0.页面结构 1.新增按钮和弹出表单:结构 2.新增按钮和弹出表单:点击新增弹出表单 3.表单样式 4.表单验证 5.表单的提交和取消功能:接口.mock相关准备 6.表单的提交 ...

  6. Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)

    这篇博客主要介绍树形控件的两个小小的功能: 下拉菜单 输入过滤框 以CSS样式为主,也会涉及到Vue组件和element组件的使用. 对于没有层级的数据,我们可以使用表格或卡片来展示.要展示或建立层级 ...

  7. 【前端】Vue+Element UI案例:通用后台管理系统-登陆不同用户显示不同菜单、动态添加路由

    文章目录 目标 代码 0.动态地显示菜单:store 1.动态注册路由 2.解决刷新后摆平问题 总代码 本篇修改的代码文件 tab.js 参考视频: VUE项目,VUE项目实战,vue后台管理系统,前 ...

  8. vue + element ui 的后台管理系统框架_从零开始搭建 VUE + Element UI后台管理系统框架...

    点击右上方红色按钮关注"web秀",让你真正秀起来 前言 后台管理系统前端框架,现在很流行的形式都是,上方和左侧都是导航菜单,中间是具体的内容.比如阿里云.七牛云.头条号.百家号等 ...

  9. Vue + Element UI 实现 登陆注册基本demo实例

    Vue + Element UI 实现权限管理系统 前端篇(二):Vue + Element 案例 导入项目 打开 Visual Studio Code,File --> add Folder ...

最新文章

  1. Simulink仿真---PMSM滞环电流控制仿真模型学习
  2. LeetCode40.组合总和|| JavaScript
  3. UI5_INFO_FETCH_FROM_DB
  4. leetcode 239. 滑动窗口最大值(单调队列)
  5. 逐行读文件_用python比较两个文件的内容是否相同
  6. LCT(Link Cut Tree)总结
  7. mina mysql_Mina源码阅读笔记(四)—Mina的连接IoConnector2
  8. 概率图模型之马尔可夫随机场
  9. java 把对象转成map_Java对象转换成Map
  10. web前端笔试试题一(含答案)
  11. sobel 边缘检测 c语言,Sobel边缘检测算法(转载)(示例代码)
  12. 08cms房产门户系统源码V8.6.1多城市版
  13. Alpha Test和Alpha Blend Shader两种处理透明的方法
  14. Uiuc计算机博士面试时间,学霸分享:UIUC生物博士onsite面试经验
  15. bandizip没有右键菜单解决办法
  16. 走进C 语言:你知道C语言程序是如何执行的吗?
  17. vue3中进行vuex的分包管理(typescript)
  18. 贝叶斯推断应用:垃圾邮件过滤
  19. docker-compose 部署 php + nginx + mysql + redis
  20. 使用Git管理SVN

热门文章

  1. mysql怎么截取时分秒_mysql获取表中日期的年月日时分秒
  2. Elasticsearch:运用 Pinned query 来提升特定的结果
  3. 【计算机视觉】关于计算机视觉(随谈)
  4. 第一次尝试miniprogram-automator
  5. -atime、-ctime、mtime、-newer
  6. 硬件知识:声控楼道灯电路
  7. 非线性优化库NLopt简介
  8. oracle右键删除表格,Oracle删除表的几种方法
  9. 大话主流分布式文件系统!
  10. SpringBoot关于文件上传配置的几种方式