From 1c44651ad2caa6a67054b8b6e4ec434e9404a10f Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 15 Dec 2023 18:30:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=85=B3=E7=B3=BB=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/monitor/topology/index.vue | 614 ++++++--------------------- 1 file changed, 126 insertions(+), 488 deletions(-) diff --git a/src/views/monitor/topology/index.vue b/src/views/monitor/topology/index.vue index 3fcbf966..8566e536 100644 --- a/src/views/monitor/topology/index.vue +++ b/src/views/monitor/topology/index.vue @@ -16,8 +16,6 @@ const graphG6Dom = ref(undefined); /**图实例对象 */ let graphChart: any = null; - - /**图DOM节点实例对象 */ const graphData = reactive({ nodes: [], @@ -30,175 +28,144 @@ const data = { // 0 基站 { id: '0', - data: { - x: 50, - y: 150, - type: 'circle-node', - color: '#fffff', - keyShape: { - r: 24, - width: 48, - height: 48, - fill: '#9EC9FF', - stroke: '#5B8FF9', - lineWidth: 2, - }, - labelShape: { - text: '基站', - position: 'bottom', - maxWidth: '200%', - offsetY: 10, - }, - labelBackgroundShape: {}, - iconShape: { - img: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg', - width: 24, - height: 24, + x: 50, + y: 150, + size: 48, + type: 'circle', + label: '基站', + labelCfg: { + position: 'bottom', + offset: 10, + style: { + fill: '#333', + stroke: '#fff', + lineWidth: 10, }, }, + style: { + fill: '#9EC9FF', + stroke: '#5B8FF9', + lineWidth: 2, + }, + icon: { + show: true, + // 可更换为其他图片地址 + img: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg', + width: 24, + height: 24, + }, }, // 1 DM { id: '1', - data: { - label: 'DM', - x: 450, - y: 450, - keyShape: { - width: 80, - height: 40, - radius: 8, - fill: '#00b050', - }, - labelShape: { - position: 'center', - text: 'DM', - fill: '#fff', // 节点标签文字颜色 - }, + x: 450, + y: 450, + label: 'DM', + labelCfg: { + position: 'center', + }, + style: { + fill: '#00b050', + stroke: '#00b050', + lineWidth: 1, }, }, // 2 O&M { id: '2', - data: { - label: 'O&M', - x: 50, - y: 450, - }, + x: 50, + y: 450, + label: 'O&M', }, // 100 EMS { id: '100', - data: { - label: 'EMS', - parentId: 'combo-ems', - x: 300, - y: 450, - }, + label: 'EMS', + comboId: 'combo-ems', + x: 300, + y: 450, }, // 190 UPF { id: '190', - data: { - parentId: 'combo-upf', - x: 300, - y: 350, - keyShape: { - width: 80, - height: 40, - radius: 8, - fill: '#d580ff', - }, - labelShape: { - position: 'center', - text: 'UPF', - fill: '#fff', // 节点标签文字颜色 - }, + comboId: 'combo-upf', + x: 300, + y: 350, + label: 'UPF', + labelCfg: { + position: 'center', + }, + style: { + fill: '#d580ff', + stroke: '#d580ff', + lineWidth: 1, }, }, // EP-IMS { id: '110', - data: { - parentId: 'combo-ims', - x: 600, - y: 350, - keyShape: { - width: 80, - height: 40, - radius: 8, - fill: '#ed7d31', - }, - labelShape: { - position: 'center', - text: 'IMS', - fill: '#fff', // 节点标签文字颜色 - }, + comboId: 'combo-ims', + x: 600, + y: 350, + label: 'IMS', + labelCfg: { + position: 'center', + }, + style: { + fill: '#ed7d31', + stroke: '#ed7d31', + lineWidth: 1, }, }, // 5GC控制面 { id: '170', - data: { - label: 'NSSF', - parentId: 'combo-5gc', - x: 300, - y: 50, - }, + label: 'NSSF', + comboId: 'combo-5gc', + x: 300, + y: 50, }, { id: '130', - data: { - label: 'AUSF', - parentId: 'combo-5gc', - x: 450, - y: 50, - }, + label: 'AUSF', + comboId: 'combo-5gc', + x: 450, + y: 50, }, { id: '140', - data: { - label: 'UDM', - parentId: 'combo-5gc', - x: 600, - y: 50, - }, + label: 'UDM', + comboId: 'combo-5gc', + x: 600, + y: 50, }, { id: '120', - data: { - label: 'AMF', - parentId: 'combo-5gc', - x: 300, - y: 150, - }, + label: 'AMF', + comboId: 'combo-5gc', + x: 300, + y: 150, }, { id: '180', - data: { - label: 'NRF', - parentId: 'combo-5gc', - x: 450, - y: 150, - }, + label: 'NRF', + comboId: 'combo-5gc', + x: 450, + y: 150, }, { id: '150', - data: { - label: 'SMF', - parentId: 'combo-5gc', - x: 300, - y: 250, - }, + label: 'SMF', + comboId: 'combo-5gc', + x: 300, + y: 250, }, { id: '160', - data: { - label: 'PCF', - parentId: 'combo-5gc', - x: 700, - y: 250, - }, + label: 'PCF', + comboId: 'combo-5gc', + x: 700, + y: 250, }, ], edges: [ @@ -206,142 +173,62 @@ const data = { id: '0-5gc', source: '0', target: 'combo-5gc', - data: {}, }, { id: '0-upf', source: '0', target: 'combo-upf', - data: { - keyShape: { - radius: 4, - controlPoints: [ - { x: 150, y: 150 }, - { x: 150, y: 350 }, - ], - lineWidth: 1, - stroke: '#d580ff', - }, - labelShape: { - text: 'N3', - position: 'end', - autoRotate: true, - offsetY: 10, - }, - labelBackgroundShape: {}, - }, }, { id: 'upf-1', source: 'combo-upf', target: '1', - data: { - keyShape: { - radius: 4, - controlPoints: [{ x: 400, y: 400 }], - lineWidth: 1, - stroke: '#d580ff', - }, - labelShape: { - text: 'N6', - position: 'start', - autoRotate: true, - offsetX: 10, - }, - labelBackgroundShape: {}, - }, }, { id: 'ems-2', source: 'combo-ems', target: '2', - data: { type: 'cubic-edge' }, }, { id: '170-120', source: '170', target: '120', - data: {}, }, { id: '130-120', source: '130', target: '120', - data: {}, }, { id: '140-120', source: '140', target: '120', - data: {}, }, { id: '140-180', source: '140', target: '180', - data: {}, }, { id: '120-180', source: '120', target: '180', - data: { - type: 'polyline-edge', - keyShape: { - endArrow: true, - routeCfg: { - /** - * 目前支持正交路由 'orth' 和地铁路由 'er' - */ - // name: 'er', - /** - * 是否开启自动避障,默认为 false - * Whether to enable automatic obstacle avoidance, default is false - */ - enableObstacleAvoidance: true, - }, - /** - * 拐弯处的圆角弧度,默认为直角,值为 0 - * The radius of the corner rounding, defaults to a right angle - */ - // radius: 20, - /** - * 拐弯处距离节点最小距离, 默认为 2 - * Minimum distance from the node at the corner, default is 5. - */ - // offset: 0, - /** - * 控制点数组,不指定时根据 A* 算法自动生成折线。若指定了,则按照 controlPoints 指定的位置进行弯折 - * An array of control points that, when not specified, automatically generates the bends according to the A* algorithm. If specified, bends are made at the position specified by controlPoints. - */ - // controlPoints: [], - }, - }, }, { id: '130-180', source: '130', target: '180', - data: { - type: 'polyline-edge', - }, }, { id: '140-150', source: '140', target: '150', - data: { - type: 'polyline-edge', - }, }, { id: '140-110', source: '140', target: '110', - data: { - type: 'polyline-edge', - }, }, { id: '120-150', @@ -359,64 +246,48 @@ const data = { id: '150-160', source: '150', target: '160', - data: { type: 'polyline-edge' }, }, { id: '160-120', source: '160', target: '120', - data: {}, }, { id: '160-180', source: '160', target: '180', - data: { - keyShape: { - endArrow: true, - }, - labelShape: { - text: 'asdf-arrow', - }, - }, }, { id: '160-110', source: '160', target: '110', - data: {}, }, { id: '150-190', source: '150', target: '190', - data: {}, }, { id: 'upf-ims', source: 'combo-upf', target: 'combo-ims', - data: { type: 'cubic-edge' }, }, { id: 'ems-5gc', source: 'combo-ems', target: 'combo-5gc', - data: { type: 'cubic-edge' }, }, { id: 'ems-upf', source: 'combo-ems', target: 'combo-upf', - data: { type: 'cubic-edge' }, }, { id: 'ems-ims', source: 'combo-ems', target: 'combo-ims', - data: { type: 'cubic-edge' }, }, ], combos: [ @@ -454,270 +325,49 @@ function initChart() { if (!graphG6Dom.value) return; console.log(graphG6Dom.value.offsetWidth, graphG6Dom.value.offsetHeight); console.log(graphG6Dom.value.clientWidth, graphG6Dom.value.clientHeight); - console.log(graphG6Dom.value.scrollWidth, graphG6Dom.value.scrollHeight); - const graph = new Graph({ + graphChart = new Graph({ container: graphG6Dom.value, height: graphG6Dom.value.clientHeight, width: graphG6Dom.value.clientWidth, - // autoFit: 'center', + fitCenter: true, modes: { - default: [ - // { - // type: 'drag-node', - // enableTransient: false, - // updateComboStructure: false, - // }, - // { - // type: 'click-select', - // itemTypes: ['node', 'edge', 'combo'], - // }, - // { - // type: 'drag-combo', - // enableTransient: true, - // updateComboStructure: true, - // }, - 'drag-combo', - 'drag-canvas', - 'click-select', - // 'zoom-canvas', - ] as any, + default: ['drag-canvas', 'zoom-canvas', 'drag-node'], // 允许拖拽画布、放缩画布、拖拽节点 }, - // 布局 力向吸引 - layout: { - type: 'force', - animated: true, - linkDistance: 280, - maxSpeed: 100, - clustering: true, - nodeClusterBy: 'parentId', - clusterNodeStrength: 80, + // 全局节点 矩形 + defaultNode: { + type: 'rect', + size: [80, 40], + style: { + fill: '#fff', + lineWidth: 1, + radius: 8, + }, + labelCfg: {}, + }, + // 全局边 三次贝塞尔曲线 + defaultEdge: { + type: 'polyline', + style: { + offset: 20, // 拐弯处距离节点最小距离 + radius: 4, // 拐弯处的圆角弧度,若不设置则为直角 + lineWidth: 1, + stroke: '#87e8de', + }, + }, + // 全局框节点 矩形 + defaultCombo: { + type: 'rect', // Combo 类型 + size: [40, 40], + // ... 其他配置 + style: { + lineWidth: 1, + }, }, - // // 主题 - // theme: { - // type: 'spec', - // base: 'light', - // specification: { - // node: { - // dataTypeField: 'parentId', - // }, - // }, - // } as any, - // // 插件 - // plugins: [ - // { - // // 避免文本过于密集导致的视觉混乱 - // type: 'lod-controller', - // disableLod: true, - // }, - // ] as any, - // // 全局节点 矩形 - // node: model => { - // const { id, data } = model; - // return { - // id, - // data: { - // type: 'rect-node', - // keyShape: { - // width: 80, - // height: 40, - // radius: 8, - // }, - // labelShape: { - // position: 'center', - // text: `${id} - ${data.label}`, - // fill: '#fff', - // }, - // animates: { - // update: [ - // { - // fields: ['opacity'], - // shapeId: 'haloShape', - // states: ['breathing'], - // iterations: Infinity, - // direction: 'alternate', - // duration: 500, - // }, - // { - // fields: ['lineWidth'], - // shapeId: 'keyShape', - // states: ['breathing'], - // iterations: Infinity, - // direction: 'alternate', - // duration: 500, - // }, - // { - // fields: ['height', 'width'], - // shapeId: 'keyShape', - // states: ['scaling'], - // iterations: Infinity, - // direction: 'alternate', - // duration: 500, - // }, - // ], - // }, - // ...data, - // }, - // }; - // }, - // // 全局边 三次贝塞尔曲线 - // edge: model => { - // const { id, source, target, data } = model; - // return { - // id, - // source, - // target, - // data: { - // type: 'polyline-edge', - // animates: { - // update: [ - // { - // fields: ['lineDash'], - // shapeId: 'keyShape', - // states: ['growing', 'running'], - // iterations: Infinity, - // duration: 2000, - // }, - // { - // fields: ['offsetDistance'], - // shapeId: 'buShape', - // states: ['circleRunning'], - // iterations: Infinity, - // duration: 2000, - // }, - // ], - // }, - // ...data, - // }, - // }; - // }, - // // 全局框节点 矩形 - // combo: model => { - // const { id, data } = model; - // return { - // id, - // data: { - // type: 'rect-combo', - // keyShape: { - // opacity: 0.8, - // padding: [20, 20, 20, 20], - // radius: 8, - // }, - // labelShape: { - // text: data.label, - // offsetY: 8, - // }, - // labelBackgroundShape: {}, - // buildIn: [ - // { - // fields: ['opacity'], - // duration: 500, - // delay: 500 + Math.random() * 500, - // }, - // ], - // buildOut: [ - // { - // fields: ['opacity'], - // duration: 200, - // }, - // ], - // animates: { - // update: [ - // { - // fields: ['width', 'height', 'x', 'y'], - // shapeId: 'keyShape', - // }, - // ], - // }, - // ...data, - // }, - // }; - // }, - // 节点状态 - // nodeState: { - // breathing: { - // haloShape: { - // opacity: 0.25, - // lineWidth: 20, - // visible: true, - // }, - // keyShape: { - // radius: 4, - // }, - // }, - // scaling: { - // keyShape: { - // width: 100, - // height: 60, - // }, - // }, - // } as any, - // edgeState: { - // growing: { - // keyShape: { - // lineWidth: 2, - // lineDash: ['100%', 0], - // }, - // }, - // running: { - // keyShape: { - // lineWidth: 2, - // lineDash: [2, 2], - // // TODO: lineDashOffset - // }, - // }, - // }, - // data, //: graphData, }); - // graph.render() - // graphChart = graph; -} -const actions = { - 'Enable/Disable Node States': { - Breathing: () => { - graphChart.getAllNodesData().forEach((node: any) => { - if (graphChart.getItemState(node.id, 'breathing')) { - graphChart.setItemState(node.id, 'breathing', false); - } else { - graphChart.setItemState(node.id, 'scaling', false); - graphChart.setItemState(node.id, 'breathing', true); - } - }); - }, - Scaling: () => { - graphChart.getAllNodesData().forEach((node: any) => { - if (graphChart.getItemState(node.id, 'scaling')) { - graphChart.setItemState(node.id, 'scaling', false); - } else { - graphChart.setItemState(node.id, 'breathing', false); - graphChart.setItemState(node.id, 'scaling', true); - } - }); - }, - }, - 'Enable/Disable Edge States': { - Growing: () => { - graphChart.getAllEdgesData().forEach((edge: any) => { - if (graphChart.getItemState(edge.id, 'growing')) { - graphChart.setItemState(edge.id, 'growing', false); - } else { - graphChart.setItemState(edge.id, 'running', false); - graphChart.setItemState(edge.id, 'growing', true); - } - }); - }, - Running: () => { - graphChart.getAllEdgesData().forEach((edge: any) => { - if (graphChart.getItemState(edge.id, 'running')) { - graphChart.setItemState(edge.id, 'running', false); - } else { - graphChart.setItemState(edge.id, 'growing', false); - graphChart.setItemState(edge.id, 'running', true); - } - }); - }, - }, -}; + graphChart.data(data); // 加载数据 + graphChart.render(); // 渲染 +} /**查询全部网元数据列表 */ function fnGetList() {} @@ -863,19 +513,7 @@ onMounted(() => {
- - - -