概述

项目刚开始用的echarts画的拓扑图,echarts有个关系图可以直接画出来,但是上个前端在拖拽功能上留了bug,我眼睛都快看瞎了,都没找出来哪里出问题,还找了各种文章借鉴学习都没搞定

后来跑到gitHub上面找了个大神写的拓扑,根据他的代码改好了,不过他用的svg画的图,所以我这份记录也是svg

注意

  1. 数据从后端获取,模拟数据已经提供,修改getData()中代码就行
  2. 缩放功能用到了d3,先安装npm install d3 --save-devmain.js中引入 import * as d3 from 'd3'; Vue.prototype.$d3 = d3
  3. 图片自己随便弄,注意图片名字和后缀名就行

代码

HTML

<template><div class="content"><!--拓扑存放位置--><svgclass="topo"id="svg"ondragover="return false"oncontextmenu="return true"@mousewheel="zooming"><!-- 已连接的线 --><linev-for="(item) in lines":key="item.x":x1="item.x1" :y1="item.y1":x2="item.x2" :y2="item.y2"style="stroke:rgb(214,214,218);stroke-width:2"/><gv-for="(item, index) in topoNodes":key="item.id"@mousedown.left.stop.prevent="moveAndLink(index, $event)"><image :xlink:href="item.symbol" width="50px" height="50px" :x="item.x" :y="item.y"></image><text :x="item.x + 25" :y="item.y + 66" style="text-anchor: middle; user-select: none;">{{item.name}}</text></g></svg></div>
</template>

JavaScript

<script>export default {name: 'SvgDemo',props: {},data() {return {res: {code: 200,data: [{name: "default",devices: [{id: "3",name: "Router",ip: "169.254.200.2",type: "router",x: 400,y: 50},{id: "1",name: "Linux",ip: "192.168.67.101",type: "server",x: 52,y: 500},{id: "5",name: "Winserver",ip: "192.168.67.200",type: "server",x: 500,y: 500},{id: "4",name: "SW",ip: "192.168.67.201",type: "switch",x: 200,y: 200}],relation: [{source: "3", target: "4", network: "Net-CSRiface_1"},//连线——————source:起点,target(目标):终点{source: "1", target: "4", network: "Net-SWiface_16"},{source: "5", target: "4", network: "Net-R4iface_0"}]}]},topoNodes: [], // topo图中的节点topoLinks: [], // topo图中的连线isMove: true,// 操作模式,默认为移动。可切换为连接模式positions: [],//更改的位置token: null}},computed: {// 动态计算节点间的连线lines() {let hash = {}const OFFSET = 20this.topoNodes.forEach((item, index) => {hash[item.id] = index})/*hash:{1: 13: 04: 35: 2},source:3 1 5,target:4 4 4*/return this.topoLinks.map(item => {const startNode = this.topoNodes[hash[Number(item.source)]]const endNode = this.topoNodes[hash[Number(item.target)]]return {x1: startNode.x + OFFSET,y1: startNode.y + OFFSET,x2: endNode.x + OFFSET,y2: endNode.y + OFFSET,}})}},created() {this.token = sessionStorage.getItem("token");this.getData();},methods: {getData() {//使用模拟数据/*this.topoNodes = this.res.data[0].devices;this.topoLinks=this.res.data[0].relation;for (let item of this.topoNodes) {item.symbol = require(`@/assets/images/${item.type}.svg`);}for (let item of this.topoLinks) {item.source = Number(item.source);item.target=Number(item.target);}console.log(this.topoNodes)*///使用接口返回数据this.$axios({url: window.config.Login_URL + "/mirror/spaces/topology", //topologymethod: "GET",headers: {MyToken: this.token,},data: {status: this.value,},}).then((res) => {if (res.data.code === 200) {this.topoNodes = res.data.data[0].devices;this.topoLinks = res.data.data[0].relation;for (let item of this.topoNodes) {item.symbol = require(`@/assets/images/${item.type}.svg`);}for (let item of this.topoLinks) {item.source = Number(item.source);item.target = Number(item.target);}//console.log('初始数据',this.topoNodes)}}).catch(() => {this.$message.error("获取失败");});},//移动事件moveAndLink(index, e) {// 判断当前模式if (this.isMove) {// 移动模式const layerX = e.layerX - this.topoNodes[index].x;const layerY = e.layerY - this.topoNodes[index].y;//实时获取更新后的坐标document.onmousemove = (e) => {this.topoNodes[index].x = e.layerX - layerX;this.topoNodes[index].y = e.layerY - layerY;}//将新坐标存进数据库//如果使用模拟数据,删除该方法document.onmouseup = () => {this.positions = [];for (let j = 0; j < this.topoNodes.length; j++) {this.positions.push({'ip': this.topoNodes[j].ip,'x': this.topoNodes[j].x,'y': this.topoNodes[j].y})}this.$axios({url: window.config.Login_URL + "/mirror/spaces/topology",method: "POST",headers: {MyToken: this.token,},data: {positions: this.positions,},}).then(() => {}).catch(() => {});document.onmousemove = nulldocument.onmouseup = null}} else {document.onmousemove = null // 重置鼠标移动事件this.isMove = true // 重置为移动模式}},// 放大缩小zooming(){var svg = this.$d3.select('#svg');var zoom = this.$d3.zoom().scaleExtent([0.4, 5]).on("zoom", function (e) {svg.selectAll('g').attr('transform',e.transform);svg.selectAll('line').attr('transform',e.transform)});svg.call(zoom)}}}
</script>

CSS

<style scoped>.content {width: 100%;display: flex;justify-content: center;align-items: center;}.topo {width: 1070px;height: 600px;}
</style>

vue使用svg画拓扑图(关系图) 拖拽 缩放相关推荐

  1. `echarts`实现关系图拖拽

    echarts 目标:echarts实现关系图拖拽 效果:当所有的节点都处在高亮的状态时,可以拖拽任何节点.当点击其中一个节点与之有直接联系的节点高亮,其他的置灰.并且高亮的节点均可拖拽.点击空白处时 ...

  2. 基于vue的svg画线_基于SVG的Vue图组件库

    基于vue的svg画线 图表 (diagram-vue) A vue component library of diagrams. Vue组件图库. View Demo 查看演示 Download S ...

  3. 使用antV-G6在angualr中画树形关系图

     使用antV-G6在angualr中画树形关系图(流量追踪图) 公司有个需求就是既要呈现出每个节点之间的关系(图里面需要带箭头,为了表现出流向关系),又要排版呈现出树状结构,也就是说是具备层次关系的 ...

  4. 解决d3.event在v7版本无效影响zoom拖拽缩放问题

    近期由于代码内关于d3版本的更新,由原来的v3 v4更新值v7.0.0,导致原有关于d3的波点图内zoom方法的拖拽缩放.tooltip提示框问题开始报错,即d3.event数据废弃了 1.设置d3图 ...

  5. vue-draggable-resizable-gorkys 可拖拽缩放的组件

    说明:组件基于vue-draggable-resizable进行二次开发. 文章引用于vue-draggable-resizable 可拖拽缩放的组件 - SegmentFault 思否 git引用于 ...

  6. vue族谱架构_vue.js中使用d3.js画家谱关系图

    项目中需要做个家谱图,网上查了好多资料没找到合适的,就自己写个简单的,方便以后查看,附上效果图 首先展示父亲.配偶.子女,三代人信息,然后选择其他人可以展开他的三代关系.如下图 下面是代码,这个关系图 ...

  7. 有哪些思维导图或其他软件适合画人物关系图?

    先说思维导图软件(以MindMaster为例) 诚然,大部分思维导图软件都是有一个中心主题,然后向两边发散.但是也有小部分思维导图软件支持"浮动主题",比如MindMaster.所 ...

  8. Vue 使用 vis-network 绘制网络关系图

    1.Vis-network visjs 提供了一个网络视图模块,提供给我们绘制网络之间的各个点.线之间的关系,这个的话就比较类似于echarts的地图,在地图上打点画线的逻辑,区别在于使用visjs可 ...

  9. vue 鼠标拖动画矩形_vue中拖动元素效果实现,以及拖拽`缩放后的元素`效果实现...

    START 番茄我又又又来写点啥了,最近被需求折磨的不要不要的,要做一个在线PPT做的网站.元素拖动算是其中一小部分的功能吧,但是还是出了很多的bug,这篇文章算是我对元素拖拽相关的记录吧. 仅以此文 ...

最新文章

  1. linux 下查mac
  2. Hibernate学习(二)
  3. java jtextarea滚动条下滑,关于JTextArea的滚动条问题
  4. 《Beginning Linux Programming》读书笔记(四)
  5. 在web开发中,如何保证对象只被创建一次之单例应用系列?
  6. JWT token信息保存
  7. mysql触发器新增或修改_mysql触发器实例 插入数据前更改数据值
  8. 盐城机电高等职业技术学校计算机专业,盐城机电高等职业技术学校
  9. 协议和代理模式的概念
  10. jQuery简单倒计时插件
  11. 看一篇就学会系列,mysql慢日志查看,本地mysql是使用phpstudy安装的
  12. 【Python成长之路】快速理解复制、浅拷贝、深拷贝
  13. 《电路原理》清华公开课 week1 支路变量、元件、KCL、KVL
  14. Android 通过shape画线,1条线2种颜色,左边线条和背景色一致,右边线条为divider颜色
  15. Visio画图(直角坐标系和relu函数)
  16. So Easy京东商城
  17. PostgreSQL,MongoDB,Neo4j,OrientDB和ArangoDB比较
  18. Whitelabel Error Page
  19. OSChina 周二乱弹 ——程序员在聊天中注意观察什么细节
  20. 目标检测指标mAP详解

热门文章

  1. 程序员们的爱情表白书
  2. 关于ISE、iMPACT等软件在Win10系统中运行遇到的问题及解决方法总结(摘自黑金教程、我没有验证过)
  3. 登陆注册协议获取sid
  4. 隐私计算的介绍-入门学习笔记(一)
  5. PHP是计算机高级语音,高级语言包括哪些
  6. 如何对scrollbar位置进行控制?
  7. 精彩分享 | 欢乐游戏 Istio 云原生服务网格三年实践思考
  8. react使用createContext
  9. 古希腊神话故事:维纳斯和阿多尼斯
  10. QPSK和16QAM基带信号解调误比特率理论限和仿真对比