vis-network绘制拓扑图

时间:2025-04-26 14:24:44
<template> <div id="mynetwork" ref="mynetwork"></div> </template> <script> const vis = require("vis-network/dist/"); export default { name: 'HelloWorld', props: { msg: String }, data() { return { nodes: null, edges: null, options: null, network: null, } }, created() { this.nodes = new vis.DataSet([ // nodes是节点 {id: 1, label: 'Node 1',level: 1}, {id: 2, label: 'Node 2',level: 2}, {id: 8, label: 'Node 8',level: 2}, {id: 9, label: 'Node 9',level: 2}, {id: 10, label: 'Node 10',level: 2}, {id: 3, label: 'Node 3',level: 2}, {id: 4, label: 'Node 4',level: 3}, {id: 5, label: 'Node 5',level: 3}, {id: 6, label: 'Node 6',level: 4}, {id: 7, label: 'Node 7',level: 5}, ]); this.edges = new vis.DataSet([ // edges是线 {from: 1, to: 2}, // 决定了节点从左往右的顺序 {from: 1, to: 3}, {from: 1, to: 8}, {from: 1, to: 9}, {from: 1, to: 10}, {from: 2, to: 4}, {from: 2, to: 5}, {from: 5, to: 6}, {from: 6, to: 7}, ]); }, mounted() { this.init() }, methods: { init() { const container = this.$refs.mynetwork; const data = { nodes: this.nodes, edges: this.edges } this.options = { autoResize: true, // 默认true,自动调整容器的大小 height: '100%', // 默认值 width: '100%', // 默认值 locale: 'cn', // 选择语言,默认英文en,cn为汉语 locales: { // 语言格式化对象 cn: { edit: '编辑', del: '删除', back: '返回', addNode: '添加节点', addEdge: '添加连线', editNode: '编辑节点', editEdge: '编辑连线', addDescription: '点击空白区域添加节点', edgeDescription: 'Click on a node and drag the edge to another node to connect them.', editEdgeDescription: 'Click on the control points and drag them to a node to connect to it.', createEdgeError: 'Cannot link edges to a cluster.', deleteClusterError: 'Clusters cannot be deleted.', editClusterError: 'Clusters cannot be edited.', }, }, // 配置模块 configure: { enabled: false, // false时不会在界面上出现各种配置项 }, // 节点模块 nodes: { chosen: true, // 对选择节点做出反应 color: { border: '#2B7CE9', background: '#97C2FD', highlight: { border: '#2B7CE9', background: '#FFEC8B' }, hover: { border: '#2B7CE9', background: '#FFC125' } }, font: { align: 'left', color: '#FFC125', size: 12 // vadjust: 10, // 标签文本的垂直位置,值越大离节点越远 }, labelHighlightBold: false, // hidden: true, // 为true不会显示节点。但仍是物理模拟的一部分 shape: 'image', image: { // 路径问题要注意,一定要存储在静态文件夹中 unselected: '/static/images/icon_normal.svg', selected: '/static/images/icon_selected.svg', }, size: 25, // 节点大小 physics: false, // 关闭物理引擎 title: '哈哈哈', // 用户悬停在节点上时显示的标题,可以是HTML元素或包含纯文本或HTML的字符串 widthConstraint: { // 节点的最小宽度与最大宽度 // maximum: 100, } }, // 边模块 edges: { // label: '哈哈哈', physics: false, smooth: { enabled: true, type: 'curvedCCW', // 平滑曲线的类型 forceDirection: 'horizontal' // 用于分层布局的配置项,可选值有: ['horizontal', 'vertical', 'none'] }, // arrows: { // 这里可以用来自定义箭头,type为image类型即可 // middle: { enabled: true, type: 'image', imageHeight: 12, imageWidth: 12, src: getOpticalRed() } // }, }, // 交互模块 interaction: { hover: true, // 启用鼠标悬停 hoverConnectedEdges: false, // 鼠标悬停在节点上时,与其连接的边不高亮显示 hideEdgesOnDrag: false, // true时拖动视图时不会绘制边。这会加快拖动时的响应速度 hideNodesOnDrag: false, // true时拖动视图时不会绘制节点 navigationButtons: true, selectConnectedEdges: false, // 选中节点时,与其连接的边不高亮 multiselect: false, // true时长时间单击(或触摸)以及控件单击将添加到选择中 tooltipDelay: 100, }, // 可视化操作: 没起作用,不知道是不是版本的问题 manipulation: { enabled: false, initiallyActive: true, addNode: true, addEdge: true, // editNode: undefined, editEdge: true, deleteNode: true, deleteEdge: true, controlNodeStyle:{ // all node options are valid. } }, // 物理引擎 physics: { enabled: true, barnesHut: { gravitationalConstant: -20000, // 斥力 springLength: 20, // 弹簧长度 avoidOverlap: 1, }, maxVelocity: 50, minVelocity: 1, stabilization: { iterations: 500, // 最大迭代次数 enabled: true, // fit: true, fit: false, // 值为false时,点击刷新后可回到刷新前的页面 }, }, // 布局 layout: { randomSeed: 2000, hierarchical: { enabled: true, levelSeparation: 100, // 层级之间的距离,太小的话箭头会盖住标签字 nodeSpacing: 100, // 节点之间的距离 treeSpacing: 100, // 树之间的距离 sortMethod: 'directed', }, }, } this.network = new vis.Network(container, data, this.options); setTimeout(() => { this.nodes.update({id: 9, label: '更新后的9'}) },10000) } } } </script> <style scoped lang="less"> #mynetwork { width: 80%; height: 60%; border: none; ::v-deep .vis-navigation { position: absolute; z-index: 2; right: 12px; top: 47.8%; .vis-zoomIn, .vis-zoomOut { width: 24px; height: 24px; margin: 4px; cursor: pointer; border: 1px solid #c0c0c0; border-radius: 2px; border-radius: 2px; &:hover { border-color: #ccc; color: #4d4d4d; } } } ::v-deep .vis-tooltip { position: absolute; visibility: visible; } } </style>