12 changed files with 462 additions and 4571 deletions
@ -0,0 +1,40 @@ |
|||||||
|
<template> |
||||||
|
<div>Use G6 in Vue</div> |
||||||
|
<div id="container" class="w-full h-full"></div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script setup lang="ts"> |
||||||
|
import { onMounted } from 'vue'; |
||||||
|
import { ExtensionCategory, Graph, register } from '@antv/g6'; |
||||||
|
import { MyLineEdge } from './utils/MyLineEdge'; |
||||||
|
import DeviceData from './utils/data.ts'; |
||||||
|
|
||||||
|
import { flattenTree, GenerateGraphData } from "@/views/testG6/utils"; |
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => { |
||||||
|
register(ExtensionCategory.EDGE, 'my-line-edge', MyLineEdge); |
||||||
|
const device = flattenTree(DeviceData) |
||||||
|
console.log(device) |
||||||
|
const graphData = new GenerateGraphData(device) |
||||||
|
|
||||||
|
const graph = new Graph({ |
||||||
|
container: document.getElementById('container')!, |
||||||
|
|
||||||
|
layout: { |
||||||
|
type: 'dagre', |
||||||
|
}, |
||||||
|
edge: { |
||||||
|
type: 'my-line-edge', |
||||||
|
}, |
||||||
|
data: { |
||||||
|
nodes: graphData.getNodes(), |
||||||
|
edges: graphData.getEdges() |
||||||
|
}, |
||||||
|
behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'], |
||||||
|
}); |
||||||
|
console.log(graphData.getEdges()) |
||||||
|
graph.render(); |
||||||
|
|
||||||
|
}); |
||||||
|
</script> |
@ -0,0 +1,51 @@ |
|||||||
|
import { BaseEdge } from '@antv/g6'; |
||||||
|
import type { PathArray } from "@antv/util"; |
||||||
|
import { Circle } from '@antv/g'; |
||||||
|
import { subStyleProps } from '@antv/g6'; |
||||||
|
|
||||||
|
|
||||||
|
export class MyLineEdge extends BaseEdge { |
||||||
|
|
||||||
|
getMarkerStyle(attributes: object) { |
||||||
|
return { |
||||||
|
r: 5, |
||||||
|
fill: '#c3d5f9', |
||||||
|
offsetPath: this.shapeMap.key, ...subStyleProps(attributes, 'marker') |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
onCreate() { |
||||||
|
const marker = this.upsert('marker', Circle, this.getMarkerStyle(this.attributes), this)!; |
||||||
|
marker.animate([{ offsetDistance: 0 }, { offsetDistance: 1 }], { |
||||||
|
duration: 3000, |
||||||
|
iterations: Infinity, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
// 这里保持你的路径逻辑
|
||||||
|
protected getKeyPath(attrs: any): PathArray { |
||||||
|
const { sourceNode, targetNode } = this; |
||||||
|
|
||||||
|
const [sx, sy] = sourceNode.getPosition(); |
||||||
|
const [tx, ty] = targetNode.getPosition(); |
||||||
|
const [x1, y1] = sourceNode.getPosition(); |
||||||
|
const [x2, y2] = targetNode.getPosition(); |
||||||
|
|
||||||
|
// 固定的主干 X
|
||||||
|
const busX = attrs.busX ?? tx; |
||||||
|
|
||||||
|
// return [
|
||||||
|
// ['M', x1, y1],
|
||||||
|
// ['L', x2, y2],
|
||||||
|
// ];
|
||||||
|
|
||||||
|
return [ |
||||||
|
['M', sx, sy], |
||||||
|
['L', busX, sy], |
||||||
|
['L', busX, ty], |
||||||
|
['L', tx, ty], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
@ -0,0 +1,226 @@ |
|||||||
|
export default [{ |
||||||
|
"id": 398, |
||||||
|
"sn": "ems1", |
||||||
|
"name": "安庆滨江夜市站", |
||||||
|
"sort": 0, |
||||||
|
"parentId": 0, |
||||||
|
"deviceId": "t00510398", |
||||||
|
"dictName": "device_one_entity_type", |
||||||
|
"level": 0, |
||||||
|
"type": 0, |
||||||
|
"description": null, |
||||||
|
"children": [ |
||||||
|
{ |
||||||
|
"id": 400, |
||||||
|
"sn": "yiming-EMS1", |
||||||
|
"name": "储能单元1", |
||||||
|
"sort": 1, |
||||||
|
"parentId": 398, |
||||||
|
"deviceId": "t00510400", |
||||||
|
"dictName": "device_two_entity_type", |
||||||
|
"level": 1, |
||||||
|
"type": 1, |
||||||
|
"description": "", |
||||||
|
"children": [ |
||||||
|
{ |
||||||
|
"id": 404, |
||||||
|
"sn": "B48100B210TF36003E-bms", |
||||||
|
"name": "BMS-1", |
||||||
|
"sort": 1, |
||||||
|
"parentId": 400, |
||||||
|
"deviceId": "t00510404", |
||||||
|
"dictName": "", |
||||||
|
"level": 2, |
||||||
|
"type": 2, |
||||||
|
"description": "", |
||||||
|
"children": null |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 408, |
||||||
|
"sn": "B48100B210TF36003E-pcs", |
||||||
|
"name": "PCS-1", |
||||||
|
"sort": 1, |
||||||
|
"parentId": 400, |
||||||
|
"deviceId": "t00510408", |
||||||
|
"dictName": "", |
||||||
|
"level": 2, |
||||||
|
"type": 3, |
||||||
|
"description": "", |
||||||
|
"children": null |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 401, |
||||||
|
"sn": "yiming-EMS2", |
||||||
|
"name": "储能单元2", |
||||||
|
"sort": 1, |
||||||
|
"parentId": 398, |
||||||
|
"deviceId": "t00510401", |
||||||
|
"dictName": "device_two_entity_type", |
||||||
|
"level": 1, |
||||||
|
"type": 1, |
||||||
|
"description": "", |
||||||
|
"children": [ |
||||||
|
{ |
||||||
|
"id": 405, |
||||||
|
"sn": "B48100B210TF36003K-bms", |
||||||
|
"name": "BMS-2", |
||||||
|
"sort": 1, |
||||||
|
"parentId": 401, |
||||||
|
"deviceId": "t00510405", |
||||||
|
"dictName": "", |
||||||
|
"level": 2, |
||||||
|
"type": 2, |
||||||
|
"description": "", |
||||||
|
"children": null |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 409, |
||||||
|
"sn": "B48100B210TF36003K-pcs", |
||||||
|
"name": "PCS-2", |
||||||
|
"sort": 1, |
||||||
|
"parentId": 401, |
||||||
|
"deviceId": "t00510409", |
||||||
|
"dictName": "", |
||||||
|
"level": 2, |
||||||
|
"type": 3, |
||||||
|
"description": "", |
||||||
|
"children": null |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
// {
|
||||||
|
// "id": 402,
|
||||||
|
// "sn": "yiming-EMS3",
|
||||||
|
// "name": "储能单元3",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 398,
|
||||||
|
// "deviceId": "t00510402",
|
||||||
|
// "dictName": "device_two_entity_type",
|
||||||
|
// "level": 1,
|
||||||
|
// "type": 1,
|
||||||
|
// "description": "",
|
||||||
|
// "children": [
|
||||||
|
// {
|
||||||
|
// "id": 406,
|
||||||
|
// "sn": "B48100B210TF36002V-bms",
|
||||||
|
// "name": "BMS-3",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 402,
|
||||||
|
// "deviceId": "t00510406",
|
||||||
|
// "dictName": "",
|
||||||
|
// "level": 2,
|
||||||
|
// "type": 2,
|
||||||
|
// "description": "",
|
||||||
|
// "children": null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "id": 410,
|
||||||
|
// "sn": "B48100B210TF36002V-pcs",
|
||||||
|
// "name": "PCS-3",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 402,
|
||||||
|
// "deviceId": "t00510410",
|
||||||
|
// "dictName": "",
|
||||||
|
// "level": 2,
|
||||||
|
// "type": 3,
|
||||||
|
// "description": "",
|
||||||
|
// "children": null
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "id": 403,
|
||||||
|
// "sn": "yiming-EMS4",
|
||||||
|
// "name": "储能单元4",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 398,
|
||||||
|
// "deviceId": "t00510403",
|
||||||
|
// "dictName": "device_two_entity_type",
|
||||||
|
// "level": 1,
|
||||||
|
// "type": 1,
|
||||||
|
// "description": "",
|
||||||
|
// "children": [
|
||||||
|
// {
|
||||||
|
// "id": 407,
|
||||||
|
// "sn": "B48100B210TF360029-bms",
|
||||||
|
// "name": "BMS-4",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 403,
|
||||||
|
// "deviceId": "t00510407",
|
||||||
|
// "dictName": "",
|
||||||
|
// "level": 2,
|
||||||
|
// "type": 2,
|
||||||
|
// "description": "",
|
||||||
|
// "children": null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "id": 411,
|
||||||
|
// "sn": "B48100B210TF360029-pcs",
|
||||||
|
// "name": "PCS-4",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 403,
|
||||||
|
// "deviceId": "t00510411",
|
||||||
|
// "dictName": "",
|
||||||
|
// "level": 2,
|
||||||
|
// "type": 3,
|
||||||
|
// "description": "",
|
||||||
|
// "children": null
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "id": 412,
|
||||||
|
// "sn": "B48100B210TF36003E-em",
|
||||||
|
// "name": "电量信息-1",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 398,
|
||||||
|
// "deviceId": "t00510412",
|
||||||
|
// "dictName": "device_two_entity_type",
|
||||||
|
// "level": 1,
|
||||||
|
// "type": 4,
|
||||||
|
// "description": "",
|
||||||
|
// "children": null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "id": 413,
|
||||||
|
// "sn": "B48100B210TF36003K-em",
|
||||||
|
// "name": "电量信息-2",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 398,
|
||||||
|
// "deviceId": "t00510413",
|
||||||
|
// "dictName": "device_two_entity_type",
|
||||||
|
// "level": 1,
|
||||||
|
// "type": 4,
|
||||||
|
// "description": "",
|
||||||
|
// "children": null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "id": 414,
|
||||||
|
// "sn": "B48100B210TF36002V-em",
|
||||||
|
// "name": "电量信息-3",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 398,
|
||||||
|
// "deviceId": "t00510414",
|
||||||
|
// "dictName": "device_two_entity_type",
|
||||||
|
// "level": 1,
|
||||||
|
// "type": 4,
|
||||||
|
// "description": "",
|
||||||
|
// "children": null
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "id": 415,
|
||||||
|
// "sn": "B48100B210TF360029-em",
|
||||||
|
// "name": "电量信息-4",
|
||||||
|
// "sort": 1,
|
||||||
|
// "parentId": 398,
|
||||||
|
// "deviceId": "t00510415",
|
||||||
|
// "dictName": "device_two_entity_type",
|
||||||
|
// "level": 1,
|
||||||
|
// "type": 4,
|
||||||
|
// "description": "",
|
||||||
|
// "children": null
|
||||||
|
// }
|
||||||
|
] |
||||||
|
}] |
@ -0,0 +1,102 @@ |
|||||||
|
import { flatMap } from 'lodash-es' |
||||||
|
import type { NodeData, EdgeData } from "@antv/g6"; |
||||||
|
|
||||||
|
type Device = any |
||||||
|
|
||||||
|
export enum DeviceType { |
||||||
|
Ems, |
||||||
|
Ecu, |
||||||
|
Bms, |
||||||
|
Pcs, |
||||||
|
Em, |
||||||
|
'Em-Measure', |
||||||
|
Tms, |
||||||
|
Ffs, |
||||||
|
Wpp, |
||||||
|
Mppt, |
||||||
|
Dgs, |
||||||
|
Cac, |
||||||
|
} |
||||||
|
|
||||||
|
export function flattenTree(tree: Device[], dep = 0): Device[] { |
||||||
|
return flatMap(tree, (node: Device,) => { |
||||||
|
const { children, ...rest } = node |
||||||
|
const current = { ...rest, dep } |
||||||
|
return [current, ...(children ? flattenTree(children, dep + 1) : [])] |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
export class GenerateGraphData { |
||||||
|
private readonly devices: Device[] = []; |
||||||
|
private nodes: NodeData[] = []; |
||||||
|
private edges: EdgeData[] = []; |
||||||
|
|
||||||
|
constructor(devices: Device[]) { |
||||||
|
this.devices = devices; |
||||||
|
this.generateNodeData() |
||||||
|
this.generateEdgeData(); |
||||||
|
} |
||||||
|
|
||||||
|
private generateNodeData() { |
||||||
|
for (const device of this.devices) { |
||||||
|
const deviceChild = this.devices.filter((item: Device) => device.id === item.parentId) |
||||||
|
this.nodes.push({ |
||||||
|
id: String(device.id), |
||||||
|
label: device.name, |
||||||
|
data: device |
||||||
|
}) |
||||||
|
if (!!deviceChild.length) { |
||||||
|
// 在每个有子节点的设备下插入一个虚拟节点
|
||||||
|
this.nodes.push({ |
||||||
|
id: `${device.id}-virtual`, |
||||||
|
label: '', |
||||||
|
type: '', |
||||||
|
style: { opacity: 0 }, |
||||||
|
size: 1, |
||||||
|
data: { |
||||||
|
type: 'virtual-node', |
||||||
|
parentId: String(device.id), |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private generateEdgeData() { |
||||||
|
for (const node of this.nodes) { |
||||||
|
|
||||||
|
const customData: Device = node.data |
||||||
|
const virtualId = `${customData.parentId}-virtual`; |
||||||
|
const findParentNode: Device = this.nodes.find((n: NodeData) => n.id === customData.parentId); |
||||||
|
if (!findParentNode) { |
||||||
|
// 如果没有找到父节点,则可能是根节点或孤立节点
|
||||||
|
if (customData.type == DeviceType.Ems) continue; |
||||||
|
this.edges.push({ |
||||||
|
source: virtualId, |
||||||
|
target: node.id, |
||||||
|
type: 'polyline', |
||||||
|
data: customData |
||||||
|
}) |
||||||
|
|
||||||
|
} else { |
||||||
|
this.edges.push({ |
||||||
|
source: customData.type === 'virtual-node' ? customData.parentId : virtualId, |
||||||
|
target: String(node.id), |
||||||
|
type: 'polyline', |
||||||
|
data: customData |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
getNodes(): NodeData[] { |
||||||
|
return this.nodes; |
||||||
|
} |
||||||
|
|
||||||
|
getEdges(): EdgeData[] { |
||||||
|
return this.edges; |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue