feat: G6版本使用稳定4.8

This commit is contained in:
TsMask
2023-12-15 18:16:58 +08:00
parent e210dd7e33
commit 44c05e964e
3 changed files with 141 additions and 469 deletions

View File

@@ -13,7 +13,7 @@
},
"dependencies": {
"@ant-design/icons-vue": "^7.0.1",
"@antv/g6": "^5.0.0-beta.28",
"@antv/g6": "^4.8.24",
"@codemirror/lang-javascript": "^6.2.1",
"@codemirror/merge": "^6.4.0",
"@codemirror/theme-one-dark": "^6.1.2",

View File

@@ -19,7 +19,7 @@
<script lang="ts" setup>
import { nextTick, watch, onMounted, onBeforeUnmount, ref } from 'vue';
import { Graph, extend, Extensions } from '@antv/g6';
import { Graph } from '@antv/g6';
const props = defineProps({
/**
@@ -45,189 +45,149 @@ const props = defineProps({
const chartGraphG6Dom = ref<HTMLElement | undefined>(undefined);
const ExtGraph = extend(Graph, {
layouts: {},
edges: {
'polyline-edge': Extensions.PolylineEdge,
'cubic-edge': Extensions.CubicEdge,
// 'custom-edge': Extensions.CubicEdge,
},
});
const data = {
nodes: [
// 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: [
@@ -235,142 +195,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: {},
},
target: 'combo-upf',
},
{
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: {},
},
target: '1',
},
{
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: [],
},
},
target: '180',
},
{
id: '130-180',
source: '130',
target: '180',
data: {
type: 'polyline-edge',
},
target: '180',
},
{
id: '140-150',
source: '140',
target: '150',
data: {
type: 'polyline-edge',
},
target: '150',
},
{
id: '140-110',
source: '140',
target: '110',
data: {
type: 'polyline-edge',
},
target: '110',
},
{
id: '120-150',
@@ -388,64 +268,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: [
@@ -477,60 +341,28 @@ const data = {
},
],
};
let graph: any = null;
/**初始化渲染图表 */
function initChart() {
if (!chartGraphG6Dom.value) return;
console.log(chartGraphG6Dom.value.offsetWidth);
console.log(chartGraphG6Dom.value.clientWidth);
console.log(chartGraphG6Dom.value.scrollWidth);
graph = new ExtGraph({
console.log(chartGraphG6Dom.value.clientHeight);
graph = new Graph({
container: chartGraphG6Dom.value,
height: 500,
height: chartGraphG6Dom.value.clientHeight,
width: chartGraphG6Dom.value.clientWidth,
// autoFit: 'center',
// fitCenter: false,
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,
type: 'force', // 指定为力导向布局
preventOverlap: true, // 防止节点重叠
linkDistance: 100, // 指定边距离为100
},
// 主题
theme: {
type: 'spec',
base: 'light',
specification: {
node: {
dataTypeField: 'parentId',
},
},
} as any,
// 插件
plugins: [
{
@@ -540,126 +372,34 @@ function initChart() {
},
] 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,
},
};
defaultNode: {
type: 'rect',
size: [80, 40],
style: {
fill: '#fff',
lineWidth: 1,
radius: 8,
},
labelCfg: {},
},
// 全局边 三次贝塞尔曲线
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,
},
};
defaultEdge: {
type: 'polyline',
style: {
offset: 20, // 拐弯处距离节点最小距离
radius: 4, // 拐弯处的圆角弧度,若不设置则为直角
lineWidth: 1,
stroke: '#87e8de',
},
},
// 全局框节点 矩形
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,
},
};
defaultCombo: {
type: 'rect', // Combo 类型
size: [40, 40],
// ... 其他配置
style: {
lineWidth: 1,
},
},
// 节点状态
nodeState: {
@@ -695,9 +435,11 @@ function initChart() {
},
},
},
data,
});
graph.data(data); // 加载数据
graph.render(); // 渲染
graph.on('node:click', (e: any) => {
const s = graph.getItemState(e.itemId);
console.log(s);

View File

@@ -1,16 +1,10 @@
<script setup lang="ts">
import { reactive, onMounted, ref } from 'vue';
import { reactive, onMounted, ref } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import ChartGraphG6 from '@/components/ChartGraphG6/index.vue';
import useI18n from '@/hooks/useI18n';
import useNeInfoStore from '@/store/modules/neinfo';
import { Extensions, Graph, GraphData, extend } from '@antv/g6';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import message from 'ant-design-vue/lib/message';
const neInfoStore = useNeInfoStore();
import useNeInfoStore from '@/store/modules/neinfo';
import { Extensions, Graph, GraphData, extend } from '@antv/g6';
import { Graph, GraphData } from '@antv/g6';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import message from 'ant-design-vue/lib/message';
const neInfoStore = useNeInfoStore();
@@ -22,14 +16,7 @@ const graphG6Dom = ref<HTMLElement | undefined>(undefined);
/**图实例对象 */
let graphChart: any = null;
/**图拓展 */
const ExtGraph = extend(Graph, {
layouts: {},
edges: {
'polyline-edge': Extensions.PolylineEdge,
'cubic-edge': Extensions.CubicEdge,
},
});
/**图DOM节点实例对象 */
const graphData = reactive<GraphData>({
@@ -468,7 +455,7 @@ function initChart() {
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 ExtGraph({
const graph = new Graph({
container: graphG6Dom.value,
height: graphG6Dom.value.clientHeight,
width: graphG6Dom.value.clientWidth,
@@ -679,66 +666,9 @@ function initChart() {
},
},
},
data//: graphData,
data, //: graphData,
});
graph.on('node:click', (e: any) => {
const s = graphChart.getItemState(e.itemId);
console.log(s);
// graph.updateData('node', {
// id: e.itemId,
// data: {
// cluster: Math.random(),
// keyShape: {
// r: 32 + Math.random() * 10 - 5,
// lineWidth: 6 + Math.random() * 6 - 3,
// stroke: '#000',
// },
// labelShape: {
// fontWeight: 700,
// },
// },
// });
});
graph.on('node:pointerenter', (e: any) => {
const { itemId } = e;
if (graph.getItemState(itemId, 'breathing')) {
graph.setItemState(itemId, 'breathing', false);
} else {
graph.setItemState(itemId, 'scaling', false);
graph.setItemState(itemId, 'breathing', true);
}
// graph.updateData('node', {
// id: itemId,
// data: {
// label: `after been hovered ${itemId}`,
// labelShape: {
// fill: '#0f0',
// },
// },
// });
});
graph.on('node:pointerleave', (e: any) => {
const { itemId } = e;
if (graph.getItemState(itemId, 'breathing')) {
graph.setItemState(itemId, 'breathing', false);
} else {
graph.setItemState(itemId, 'scaling', false);
graph.setItemState(itemId, 'breathing', true);
}
// graph.updateData('node', {
// id: itemId,
// data: {
// label: 'label before been hovered',
// labelShape: {
// fill: '#000',
// },
// },
// });
});
graph.render()
graphChart = graph;
}