Browse Source

feat: topo动画流程已经em指向

main
betaqi 3 weeks ago
parent
commit
bf1d020d89
  1. 11
      src/views/testG6/components/Node.vue
  2. 31
      src/views/testG6/index.vue
  3. 52
      src/views/testG6/utils/MyLineEdge.ts
  4. 43
      src/views/testG6/utils/MyNode.ts
  5. 46
      src/views/testG6/utils/index.ts
  6. 2
      vite.config.ts

11
src/views/testG6/components/Node.vue

@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
<div>node</div>
</template>
<style scoped lang="scss">
</style>

31
src/views/testG6/index.vue

@ -1,17 +1,18 @@
<template> <template>
<div>Use G6 in Vue</div>
<div id="container" class="w-full h-full"></div> <div id="container" class="w-full h-full"></div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import DeviceData from './utils/data'; import DeviceData from './utils/data';
import { MyLineEdge } from './utils/MyLineEdge'; import { EmLineEdge, MyLineEdge } from './utils/MyLineEdge';
import { DeviceType, flattenTree, GenerateGraphData } from "./utils"; import { DeviceType, flattenTree, GenerateGraphData, NODE_SIZE } from "./utils";
import { ExtensionCategory, Graph, register } from '@antv/g6'; import { ExtensionCategory, Graph, register } from '@antv/g6';
import { UserCardNode } from "@/views/testG6/utils/MyNode";
onMounted(() => { onMounted(() => {
register(ExtensionCategory.EDGE, 'em-line-edge', EmLineEdge)
register(ExtensionCategory.NODE, 'user-card-node', UserCardNode);
register(ExtensionCategory.EDGE, 'my-line-edge', MyLineEdge); register(ExtensionCategory.EDGE, 'my-line-edge', MyLineEdge);
const device = flattenTree(DeviceData) const device = flattenTree(DeviceData)
const graphData = new GenerateGraphData(device) const graphData = new GenerateGraphData(device)
@ -26,8 +27,15 @@ onMounted(() => {
nodesep: 50, nodesep: 50,
ranksep: 50, ranksep: 50,
}, },
edge: { // edge: {
type: 'my-line-edge', // type: 'my-line-edge',
// },
node: {
type: 'user-card-node',
style: {
size: NODE_SIZE,
customData: (d: any) => d.data,
},
}, },
data: { data: {
nodes: graphData.getNodes(), nodes: graphData.getNodes(),
@ -48,21 +56,22 @@ onMounted(() => {
); );
const [x, y] = graph.getElementPosition(root.id); const [x, y] = graph.getElementPosition(root.id);
console.log(x, y)
console.log(emNodes)
graph.updateNodeData( graph.updateNodeData(
emNodes.map((n, idx) => ({ emNodes.map((n, idx) => {
//
return {
id: n.id, id: n.id,
style: Object.assign( style: Object.assign(
{}, {},
n.style, n.style,
{ // Em { // Em
x: x + 100, x: x + NODE_SIZE[0] * 2,
y: -y - (emNodes.length * 10) + (idx * 60), y: -y - (emNodes.length * 10) + (idx * 60),
}, },
) )
})) }
})
); );
await graph.draw(); await graph.draw();

52
src/views/testG6/utils/MyLineEdge.ts

@ -2,7 +2,7 @@ import { BaseEdge } from '@antv/g6';
import type { PathArray } from "@antv/util"; import type { PathArray } from "@antv/util";
import { Circle } from '@antv/g'; import { Circle } from '@antv/g';
import { subStyleProps } from '@antv/g6'; import { subStyleProps } from '@antv/g6';
import type { Device } from "./index"; import { type Device, NODE_SIZE } from "./index";
export class MyLineEdge extends BaseEdge { export class MyLineEdge extends BaseEdge {
@ -38,28 +38,14 @@ export class MyLineEdge extends BaseEdge {
// }); // });
} }
// 这里保持你的路径逻辑
protected getKeyPath(attrs: any): PathArray { protected getKeyPath(attrs: any): PathArray {
// const { sourceNode, targetNode } = this;
const [sourcePoint, targetPoint] = this.getEndpoints(attrs, false) const [sourcePoint, targetPoint] = this.getEndpoints(attrs, false)
const [sx, sy] = [sourcePoint[0], sourcePoint[1]]; const [sx, sy] = [sourcePoint[0], sourcePoint[1]];
const [tx, ty] = [targetPoint[0], targetPoint[1]]; const [tx, ty] = [targetPoint[0], targetPoint[1]];
// const prev = this.context.model.getRelatedEdgesData(this.sourceNode.id) // 获取源节点的相关边数据
// .find((edge) => edge.target === this.targetNode.id) as Device;
// console.log(prev)
// const [sx, sy] = sourceNode.getPosition();
// const [tx, ty] = targetNode.getPosition();
// const [x1, y1] = sourceNode.getPosition();
// const [x2, y2] = targetNode.getPosition();
// 固定的主干 X // 固定的主干 X
const busX = attrs.busX ?? tx; const busX = attrs.busX ?? tx;
// return [
// ['M', x1, y1],
// ['L', x2, y2],
// ];
return [ return [
['M', sx, sy], ['M', sx, sy],
['L', busX, sy], ['L', busX, sy],
@ -70,3 +56,39 @@ export class MyLineEdge extends BaseEdge {
} }
export class EmLineEdge extends BaseEdge {
getMarkerStyle(attributes: object) {
return {
r: 4,
fill: '#c3d5f9',
offsetPath: this.shapeMap.key, ...subStyleProps(attributes, 'marker')
};
}
onCreate() {
const marker = this.upsert('marker', Circle, this.getMarkerStyle(this.attributes), this)!;
const delay = 0;
marker.animate(
[{ offsetDistance: 0 }, { offsetDistance: 1 }],
{
duration: 3000,
iterations: Infinity,
delay,
}
);
}
getKeyPath(attributes: any): PathArray {
const [sourcePoint, targetPoint] = this.getEndpoints(attributes,false);
return [
['M', sourcePoint[0], sourcePoint[1]],
['L', targetPoint[0] / 2 + (1 / 2) * sourcePoint[0], sourcePoint[1]],
['L', targetPoint[0] / 2 + (1 / 2) * sourcePoint[0], targetPoint[1]],
['L', targetPoint[0], targetPoint[1]],
];
}
}

43
src/views/testG6/utils/MyNode.ts

@ -0,0 +1,43 @@
import { Graph, register, Rect, ExtensionCategory } from '@antv/g6';
import { NODE_SIZE } from "./index";
export class UserCardNode extends Rect {
get nodeData() {
return this.context.graph.getNodeData(this.id);
}
get data() {
return this.nodeData.data || {};
}
// 用户名样式
getUsernameStyle(attributes: any) {
return {
// x: -20,
text: this.data.name || '',
fontSize: 12,
fill: '#262626',
fontWeight: 'bold',
textAlign: 'center',
textBaseline: 'middle',
};
}
drawUsernameShape(attributes: any, container: any) {
if (!attributes.customData.name) return;
const usernameStyle = this.getUsernameStyle(attributes);
this.upsert('username', 'text', usernameStyle, container);
}
render(attributes: any, container: any) {
// 渲染基础矩形
super.render(attributes, container);
this.drawUsernameShape(attributes, container);
}
}

46
src/views/testG6/utils/index.ts

@ -5,6 +5,8 @@ import type { NodeStyle } from "@antv/g6/lib/spec/element/node";
export type Device = any export type Device = any
export const NODE_SIZE: [number, number] = [100, 36]
export enum DeviceType { export enum DeviceType {
Ems, Ems,
Ecu, Ecu,
@ -22,23 +24,17 @@ export enum DeviceType {
const VIRTUAL_NODE = 'virtual-node' const VIRTUAL_NODE = 'virtual-node'
const edgeDefaultStyle: EdgeStyle = { // const nodeDefaultStyle: NodeStyle = {
router: { // ports: [
type: 'orth', // { key: 'top', placement: [0.5, 0], r: 0 },
}, // // { key: 'bottom', placement: [0.5, 1], r: 0 },
} // { key: 'left', placement: [0, 0.5], r: 0 },
// { key: 'right', placement: [1, 0.5], r: 0 }
const nodeDefaultStyle: NodeStyle = { // ]
ports: [ // }
{ key: 'top', placement: [0.5, 0], r: 0 },
{ key: 'bottom', placement: [0.5, 0.98], r: 0 },
{ key: 'left', placement: [0, 0.5], r: 0 },
{ key: 'right', placement: [1, 0.5], r: 0 }
]
}
export function flattenTree(tree: Device[], depth = 0): Device[] { export function flattenTree(tree: Device[], depth = 1): Device[] {
return flatMap(tree, (node: Device,) => { return flatMap(tree, (node: Device,) => {
const { children, ...rest } = node const { children, ...rest } = node
const current = { ...rest, depth } const current = { ...rest, depth }
@ -64,11 +60,14 @@ export class GenerateGraphData {
const isNeedPoint = device.type === DeviceType.Ems || device.type === DeviceType['Em-Measure'] || device.type === DeviceType.Em const isNeedPoint = device.type === DeviceType.Ems || device.type === DeviceType['Em-Measure'] || device.type === DeviceType.Em
this.nodes.push({ this.nodes.push({
id: String(device.id), id: String(device.id),
type: 'user-card-node',
label: device.name, label: device.name,
data: device, data: device,
style: Object.assign(isNeedPoint ? nodeDefaultStyle : {}, style: Object.assign(
{ {
labelText: device.name // labelText: device.name,
opacity: .3,
deviceName: (d: any) => d.data.name,
}) })
}) })
@ -102,12 +101,12 @@ export class GenerateGraphData {
this.edges.push({ this.edges.push({
source: customData.parentId, source: customData.parentId,
target: String(node.id), target: String(node.id),
type: 'polyline', type: 'my-line-edge',
data: customData, data: customData,
style: edgeDefaultStyle,
}) })
continue; continue;
} }
//
if (findParentNode) { if (findParentNode) {
if (this.isEms(customData.type)) continue; if (this.isEms(customData.type)) continue;
@ -116,12 +115,8 @@ export class GenerateGraphData {
this.edges.push({ this.edges.push({
target: String(customData.parentId), target: String(customData.parentId),
source: String(node.id), source: String(node.id),
type: 'polyline', type: 'em-line-edge',
data: customData, data: customData,
style: Object.assign(edgeDefaultStyle, {
sourcePort: 'bottom',
targetPort: 'right',
}),
}) })
continue; continue;
} }
@ -129,9 +124,8 @@ export class GenerateGraphData {
this.edges.push({ this.edges.push({
source: virtualId, source: virtualId,
target: String(node.id), target: String(node.id),
type: 'polyline', type: 'my-line-edge',
data: customData, data: customData,
style: edgeDefaultStyle,
}) })
} }
} }

2
vite.config.ts

@ -65,7 +65,7 @@ export default defineConfig({
host: '0.0.0.0', host: '0.0.0.0',
proxy: { proxy: {
'/remoteServer': { '/remoteServer': {
target: 'http://192.168.1.99:8080/', target: 'http://192.168.1.199:8080/',
changeOrigin: true, changeOrigin: true,
secure: false, secure: false,
ws: true, ws: true,

Loading…
Cancel
Save