RelationMap图谱--VUE,真实项目提供mock数据

RelationMap官网: 在线配置官网(可以把数据放进去,直接看效果)

VUE2 效果:左侧列表栏,点击右侧显示对应的图谱

代码:按照代码直接贴过去,直接出效果

relationMap/index.vue

<template><div class="graphBody"><List :list="list" @select-Graph="getGraph" /><Graph v-if="showGraph" :key="graphItem.rootId" :item="graphItem" /></div>
</template><script lang="ts">
import { getUuid } from "@/utils/generateUuid";import List from "./list/index.vue";
import Graph from "./graph/index.vue";
import mockInfo from "./mock.json";export default {components: {List,Graph,},data() {return {list: [],showGraph: false,graphItem: {},};},methods: {initListData() {this.list = mockInfo.data;},getGraph(item) {const data = {id: getUuid(),name: item.globalVariable.name,DefineType: item.globalVariable.defineType,ActualType: item.globalVariable.actualType,children: [],};const graphMap = new Map();item.callFunction.forEach((item) => {item.call.forEach((call) => {const fileName = call.location.split("/").pop();const secondNode = {id: getUuid(),fileName: fileName,location: call.location,children: [],};const threeNode = {id: getUuid(),functionName: item.functionName,children: [{id: getUuid(),startRow: call.startRow,endRow: call.endRow,startColumn: call.startColumn,endColumn: call.endColumn,mode: call.mode,},],};// 如果没有相同文件if (!graphMap.has(call.location)) {secondNode.children.push(threeNode);graphMap.set(call.location, secondNode);} else {const copy = graphMap.get(call.location);copy.children[0].children.push({id: getUuid(),startRow: call.startRow,endRow: call.endRow,startColumn: call.startColumn,endColumn: call.endColumn,});graphMap.set(call.location, copy);}});const valuesIterator = graphMap.values();const valuesArray = Array.from(valuesIterator);data.children.push(...valuesArray);graphMap.clear();});// 合并具有相同 location 属性的对象的 children 属性const mergedData = data.children.reduce((acc, obj) => {const existingObj = acc.find((item) => item.location === obj.location);if (existingObj) {existingObj.children = existingObj.children.concat(obj.children);} else {acc.push(obj);}return acc;}, []);const newValue = { ...data, children: mergedData };const { nodes, edges } = this.convertToNodesAndLines(newValue);const graphData = {rootId: newValue.id,nodes,lines: edges,};this.graphItem = graphData;if (this.graphItem) {this.showGraph = true;}},convertToNodesAndLines(data) {const treeToNode = (node, parentId) => {const result = [];const { children, ...nodeData } = node;result.push({id: node.id,text: node.id,data: nodeData,});if (node.children && node.children.length > 0) {node.children.forEach((item) => {result.push(...treeToNode(item, node.id));});}return result;};const nodeArray = treeToNode(data, data.id);const treeToEdge = (node) => {const links = [];if (node.children && node.children.length > 0) {node.children.forEach((item) => {const to = item.id;const from = node.id;links.push({id: `${to}->${from}`,to,from,});links.push(...treeToEdge(item));});}return links;};const edgeArray = treeToEdge(data);return { nodes: nodeArray, edges: edgeArray };},},mounted() {this.initListData();},
};
</script><style scoped>
.graphBody {height: 100%;border-radius: 4px;border: 1px solid #222529;background: #191c1f;display: flex;
}::-webkit-scrollbar {display: block;
}::-webkit-scrollbar-thumb {background: #393d45;
}
</style>

使用的方法util/generateUuid.js

import { v1 as uuidv1 } from 'uuid'// 去除-携带时间戳-uuid
export function getUuid() {// const timestamp = new Date().getTime()// 生成UUID时去掉连字符const uuid = uuidv1().replace(/-/g, '')// 截取前8位作为8位UUIDconst eightDigitUuid = uuid.substring(0, 12)return `${eightDigitUuid}`
}

relationMap/graph/index.vue

<template><div><div id="relation-graph-container" class="graph-wrapper"><RelationGraph ref="graphRef" :options="graphOptions"><template slot="node" slot-scope="{ node }"><div:class="`node-container node-type`"@click="nodeClick(node.data)"><spanv-if="node.data?.DefineType || node.data?.ActualType"class="type-style"><div class="type-title">{{ node.data.name }}</div><div class="content word-hidden type-content"><p>DefineType: {{ node.data.DefineType }}</p><p>ActualType: {{ node.data.ActualType }}</p></div></span><span v-if="node.data?.location" class="file-style"><div class="file-title"><div>{{ node.data.fileName || node.data.name }}</div></div><div><span class="content word-hidden file-path">路径: {{ node.data?.location }}</span></div></span><div v-if="node.data?.functionName" class="function-style"><div><span clsss="content word-hidden1">函数名:{{ node.data?.functionName }}</span></div></div><div v-if="node.data?.startRow" class="rowRolumn-style"><span clsss="content word-hidden">行号:{{ node.data?.startRow }} 列号:{{node.data?.startColumn}}-{{ node.data?.endColumn }}</span><span><span>【{{ node.data.mode === "read" ? "读取" : "写入" }}】</span></span></div></div></template></RelationGraph></div></div>
</template><script>
import RelationGraph from "relation-graph";
import { set } from "vue";
export default {name: "Graph",components: {RelationGraph,},props: {item: Object,},data() {return {graphOptions: {backgroundImageNoRepeat: true,moveToCenterWhenRefresh: false,zoomToFitWhenRefresh: false,defaultNodeBorderWidth: 0,defaultNodeShape: 1,layouts: [{label: "中心",layoutName: "tree",from: "left",},],},};},mounted() {this.$refs.graphRef.setJsonData(this.item, (graphInstance) => {});},
};
</script>
<style scoped>
.node-container {width: 240px;min-height: 40px;border-radius: 4px;background-color: #484750;
}.type-style {height: 120px;
}.type-title {color: #4880ff;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;padding: 8px 12px;text-align: left;border-radius: 4px;border-bottom: 1px solid #383b3e;
}.type-content {text-align: left;line-height: 22px;padding: 3px 6px;
}.file-style {height: 120px;border-radius: 4px;
}.file-title {overflow: hidden;text-overflow: ellipsis;white-space: nowrap;background-color: #387dff;padding: 8px 12px;text-align: left;border-radius: 4px;
}.file-path {text-align: left;line-height: 22px;padding: 3px 6px;
}.function-style {height: 40px;line-height: 40px;text-align: left;background: #aabee3;border-radius: 4px;padding: 0 4px;color: #000;
}.rowRolumn-style {height: 40px;line-height: 40px;text-align: left;padding: 0 4px;border-radius: 2px;
}.content {padding: 4px 2px 2px;width: 240px;align-items: left;
}.word-hidden {word-break: break-all;text-overflow: ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;
}.word-hidden1 {word-break: break-all;text-overflow: ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 1;overflow: hidden;
}
</style>
<style>
.graph-wrapper {height: calc(100vh - 160px);width: 1200px;
}.c-current-zoom {color: #999999 !important;
}.relation-graph .rel-map {background-color: #191c1f !important;
}.relation-graph .rel-toolbar .c-mb-button:hover {background-color: rgba(153, 153, 153, 0.5) !important;
}.relation-graph .rel-node-checked {width: 100% !important;box-shadow: 0 0px 5px 2px #191c1f !important;
}
</style>

relationMap/list/index.vue

该页面使用了虚拟滚动RecycleScroller,需要安装一下,参考文档: 虚拟滚动

安装: npm i vue-virtual-scroller

main.ts: 

  1. // vue virtual scroller

  2. import "vue-virtual-scroller/dist/vue-virtual-scroller.css" // 引入它的 css

  3. import VueVirtualScroller from "vue-virtual-scroller" // 引入它

  4. Vue.use(VueVirtualScroller) //

<template><RecycleScrollerclass="scroller":items="list":item-size="36"key-field="id"v-slot="{ item }"><div class="user" @click="selectGraph(item)"><span style="margin-left: 16px"> {{ item.globalVariable.name }}</span></div></RecycleScroller>
</template><script>
export default {props: {list: Array,},methods: {selectGraph(item) {this.$emit("select-Graph", item);},},
};
</script><style scoped>
.scroller {height: 800px;width: 240px;
}.user {height: 36px;position: relative;display: flex;align-items: center;color: #fff;overflow: hidden;text-overflow: ellipsis;font-family: "Source Han Sans CN";font-size: 14px;font-style: normal;font-weight: 700;line-height: 20px; /* 142.857% */
}
.user:hover {background: #222529;
}
/* 在:hover状态下添加before伪类的样式 */
.user:hover::before {content: ""; /* 必须有content属性才能显示 */display: block;width: 3px;height: 36px;position: absolute;left: 0;top: 0;background-color: #4880ff;
}
</style>

mock.json 数据量太大了,这个页面放不下了,看这里:mock.json

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/696313.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【中级软件设计师】上午题3-数据结构(查漏补缺版)

上午题3-数据结构 0 前言1 时间、空间复杂度2 串2.1 串的模式匹配 3 矩阵4 图4.1 邻接矩阵和邻接表 5 查找6 哈希表、7 树7.1 B树 0 前言 因为我之前考研系统地学习过数据结构和操作系统&#xff0c;这两部分的笔记不完整 1 时间、空间复杂度 指数<阶乘<n次方阶 使用队…

揭秘 HTTP 代理:增强在线活动的安全性和匿名性

HTTP 代理在保护您的在线隐私、增强安全性以及允许访问受限内容方面发挥着关键作用。了解 HTTP 代理的工作原理以及如何有效地利用它们可以让您掌控自己的在线状态和浏览体验。让我们深入研究 HTTP 代理的世界&#xff0c;探索它们的优势、应用程序以及最大化其效用的最佳实践。…

浪潮信息企业级存储逆势增长 市场份额位列中国前二

2023年&#xff0c;中国企业级存储市场竞争激烈&#xff0c;在挑战重重之下&#xff0c;浪潮信息仍然实现逆势增长&#xff0c;销售额增幅达4.7%&#xff0c;市场份额相比2022年扩大0.6%&#xff0c;位列中国前二。另外&#xff0c;在高端和全闪存阵列细分市场&#xff0c;浪潮…

NSSCTF | [LitCTF 2023]我Flag呢?

这道题没啥好说的&#xff0c;题目标签为源码泄露&#xff0c;我们直接CtrlU查看网页源码就能在最后找到flag 本题完

浦语大模型笔记

书生浦语大模型全链路开源体系 浦语大模型全链路开源体系大模型成为发展通用人工智能的重要途径书生浦语 2.0&#xff08;InternLM2&#xff09;核心理念书生浦语 2.0&#xff08;InternLM2&#xff09;的主要亮点主要亮点 1&#xff1a;超长上下文支持主要亮点 2&#xff1a;性…

Java面试八股之Java中的IO流分为几种

Java中的IO流分为几种 按数据单位分类&#xff1a; 字节流&#xff08;Byte Stream&#xff09;&#xff1a;以字节&#xff08;8位二进制数&#xff09;为基本单位进行数据读写。字节流适合处理所有类型的数据&#xff0c;包括文本、图像、音频、视频等二进制文件。抽象基类…

ECMAScript 2024 新特性

ECMAScript 2024 新特性 ECMAScript 2024, the 15th edition, added facilities for resizing and transferring ArrayBuffers and SharedArrayBuffers; added a new RegExp /v flag for creating RegExps with more advanced features for working with sets of strings; and …

Python练习04

目录 制作一个简易的注册登陆系统 实现过程 声明需要用到的库 构造一个判断用户文件是否存在的函数 构造一个存储用户文件的函数 制作UI 制作系统主体 运行效果 制作一个简易的注册登陆系统 通过所学知识制作一个简易的注册登陆系统&#xff0c;要求可以存储账户及密码&#…

疯狂为你省钱 - Al一键虚拟试衣整合包

在今天的数字时代&#xff0c;中小服装商家以及各种带货人&#xff0c;面临着各种挑战&#xff0c;其中之一就是模特拍摄的高成本。为此&#xff0c;一个名为OMS-Diffusion的新开源项目应运而生&#xff0c;旨在帮助大家通过虚拟试衣来降低成本。使用这个工具&#xff0c;只需要…

SSRF(服务器端请求伪造)的学习以及相关例题(上)

目录 一、SSRF的介绍 二、漏洞产生的原因 三、利用SSRF可以实现的效果&#xff08;攻击方式&#xff09; 四、SSRF的利用 五、SSRF中的函数 file_get_content() 、fsockopen() 、curl_exec() 1.file_get_content()&#xff1a; 2.fsockopen(): 3.curl_exec()&#xff1…

【C++】string类的使用④(字符串操作String operations || 常量成员Member constants)

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; STL || C 目录 前言&#x1f525;字符串操作&#xff08;String operations&#xff09;c_strdataget_allocatorcopyfindrfindfind_first_offind_last_offind_first_not_offind_last_not…

Android 老年模式功能 放大字体

1 配置属性 <attr name"text_size_16" format"dimension"/><attr name"text_size_18" format"dimension"/><attr name"text_size_14" format"dimension"/><attr name"text_size_12&quo…