vue使用svg画拓扑图(关系图) 拖拽 缩放
概述
项目刚开始用的echarts画的拓扑图,echarts有个关系图可以直接画出来,但是上个前端在拖拽功能上留了bug,我眼睛都快看瞎了,都没找出来哪里出问题,还找了各种文章借鉴学习都没搞定
后来跑到gitHub上面找了个大神写的拓扑,根据他的代码改好了,不过他用的svg画的图,所以我这份记录也是svg
注意
- 数据从后端获取,模拟数据已经提供,修改getData()中代码就行
- 缩放功能用到了d3,先安装npm install d3 --save-dev,main.js中引入
import * as d3 from 'd3'; Vue.prototype.$d3 = d3
- 图片自己随便弄,注意图片名字和后缀名就行
代码
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画拓扑图(关系图) 拖拽 缩放相关推荐
- `echarts`实现关系图拖拽
echarts 目标:echarts实现关系图拖拽 效果:当所有的节点都处在高亮的状态时,可以拖拽任何节点.当点击其中一个节点与之有直接联系的节点高亮,其他的置灰.并且高亮的节点均可拖拽.点击空白处时 ...
- 基于vue的svg画线_基于SVG的Vue图组件库
基于vue的svg画线 图表 (diagram-vue) A vue component library of diagrams. Vue组件图库. View Demo 查看演示 Download S ...
- 使用antV-G6在angualr中画树形关系图
使用antV-G6在angualr中画树形关系图(流量追踪图) 公司有个需求就是既要呈现出每个节点之间的关系(图里面需要带箭头,为了表现出流向关系),又要排版呈现出树状结构,也就是说是具备层次关系的 ...
- 解决d3.event在v7版本无效影响zoom拖拽缩放问题
近期由于代码内关于d3版本的更新,由原来的v3 v4更新值v7.0.0,导致原有关于d3的波点图内zoom方法的拖拽缩放.tooltip提示框问题开始报错,即d3.event数据废弃了 1.设置d3图 ...
- vue-draggable-resizable-gorkys 可拖拽缩放的组件
说明:组件基于vue-draggable-resizable进行二次开发. 文章引用于vue-draggable-resizable 可拖拽缩放的组件 - SegmentFault 思否 git引用于 ...
- vue族谱架构_vue.js中使用d3.js画家谱关系图
项目中需要做个家谱图,网上查了好多资料没找到合适的,就自己写个简单的,方便以后查看,附上效果图 首先展示父亲.配偶.子女,三代人信息,然后选择其他人可以展开他的三代关系.如下图 下面是代码,这个关系图 ...
- 有哪些思维导图或其他软件适合画人物关系图?
先说思维导图软件(以MindMaster为例) 诚然,大部分思维导图软件都是有一个中心主题,然后向两边发散.但是也有小部分思维导图软件支持"浮动主题",比如MindMaster.所 ...
- Vue 使用 vis-network 绘制网络关系图
1.Vis-network visjs 提供了一个网络视图模块,提供给我们绘制网络之间的各个点.线之间的关系,这个的话就比较类似于echarts的地图,在地图上打点画线的逻辑,区别在于使用visjs可 ...
- vue 鼠标拖动画矩形_vue中拖动元素效果实现,以及拖拽`缩放后的元素`效果实现...
START 番茄我又又又来写点啥了,最近被需求折磨的不要不要的,要做一个在线PPT做的网站.元素拖动算是其中一小部分的功能吧,但是还是出了很多的bug,这篇文章算是我对元素拖拽相关的记录吧. 仅以此文 ...
最新文章
- linux 下查mac
- Hibernate学习(二)
- java jtextarea滚动条下滑,关于JTextArea的滚动条问题
- 《Beginning Linux Programming》读书笔记(四)
- 在web开发中,如何保证对象只被创建一次之单例应用系列?
- JWT token信息保存
- mysql触发器新增或修改_mysql触发器实例 插入数据前更改数据值
- 盐城机电高等职业技术学校计算机专业,盐城机电高等职业技术学校
- 协议和代理模式的概念
- jQuery简单倒计时插件
- 看一篇就学会系列,mysql慢日志查看,本地mysql是使用phpstudy安装的
- 【Python成长之路】快速理解复制、浅拷贝、深拷贝
- 《电路原理》清华公开课 week1 支路变量、元件、KCL、KVL
- Android 通过shape画线,1条线2种颜色,左边线条和背景色一致,右边线条为divider颜色
- Visio画图(直角坐标系和relu函数)
- So Easy京东商城
- PostgreSQL,MongoDB,Neo4j,OrientDB和ArangoDB比较
- Whitelabel Error Page
- OSChina 周二乱弹 ——程序员在聊天中注意观察什么细节
- 目标检测指标mAP详解