ConnectionGraph 连接图
节点 + 边的关系图,节点未指定坐标时自动均匀放置在圆周上。
基础用法
数据通过 props 传入,纯 SVG 渲染,无第三方图表库依赖。
配色取自 --viz-1..8 token,色盲友好。
背景 视口
<script setup lang="ts">
import { CfConnectionGraph } from '@chufix-design/vue';
const nodes = [
{ id: 'web', label: 'Web' },
{ id: 'api', label: 'API' },
{ id: 'auth', label: 'Auth' },
{ id: 'db', label: 'DB' },
{ id: 'cache', label: 'Cache' },
{ id: 'queue', label: 'Queue' },
];
const edges = [
{ source: 'web', target: 'api', weight: 4 },
{ source: 'api', target: 'auth', weight: 2 },
{ source: 'api', target: 'db', weight: 5 },
{ source: 'api', target: 'cache', weight: 3 },
{ source: 'api', target: 'queue', weight: 1.5 },
{ source: 'queue', target: 'db', weight: 1 },
];
</script>
<template>
<CfConnectionGraph :nodes="nodes" :edges="edges" />
</template> <script setup>
import { CfConnectionGraph } from '@chufix-design/vue';
const nodes = [
{ id: 'web', label: 'Web' },
{ id: 'api', label: 'API' },
{ id: 'auth', label: 'Auth' },
{ id: 'db', label: 'DB' },
{ id: 'cache', label: 'Cache' },
{ id: 'queue', label: 'Queue' },
];
const edges = [
{ source: 'web', target: 'api', weight: 4 },
{ source: 'api', target: 'auth', weight: 2 },
{ source: 'api', target: 'db', weight: 5 },
{ source: 'api', target: 'cache', weight: 3 },
{ source: 'api', target: 'queue', weight: 1.5 },
{ source: 'queue', target: 'db', weight: 1 },
];
</script>
<template>
<CfConnectionGraph :nodes="nodes" :edges="edges" />
</template> import { CfConnectionGraph } from '@chufix-design/react';
export default function Demo() {
const nodes = [
{ id: 'web', label: 'Web' },
{ id: 'api', label: 'API' },
{ id: 'auth', label: 'Auth' },
{ id: 'db', label: 'DB' },
{ id: 'cache', label: 'Cache' },
{ id: 'queue', label: 'Queue' },
];
const edges = [
{ source: 'web', target: 'api', weight: 4 },
{ source: 'api', target: 'auth', weight: 2 },
{ source: 'api', target: 'db', weight: 5 },
{ source: 'api', target: 'cache', weight: 3 },
{ source: 'api', target: 'queue', weight: 1.5 },
{ source: 'queue', target: 'db', weight: 1 },
];
return (
<>
<CfConnectionGraph nodes={nodes} edges={edges} />
</>
);
} import { CfConnectionGraph } from '@chufix-design/react';
export default function Demo() {
const nodes = [
{ id: 'web', label: 'Web' },
{ id: 'api', label: 'API' },
{ id: 'auth', label: 'Auth' },
{ id: 'db', label: 'DB' },
{ id: 'cache', label: 'Cache' },
{ id: 'queue', label: 'Queue' },
];
const edges = [
{ source: 'web', target: 'api', weight: 4 },
{ source: 'api', target: 'auth', weight: 2 },
{ source: 'api', target: 'db', weight: 5 },
{ source: 'api', target: 'cache', weight: 3 },
{ source: 'api', target: 'queue', weight: 1.5 },
{ source: 'queue', target: 'db', weight: 1 },
];
return (
<>
<CfConnectionGraph nodes={nodes} edges={edges} />
</>
);
} 微服务拓扑
7 个服务、7 条连线,展示典型 gateway 分发模式。
背景 视口
<script setup lang="ts">
import { CfConnectionGraph } from '@chufix-design/vue';
const nodes = [
{ id: 'gateway', label: 'Gateway', size: 12, colorIndex: 0 },
{ id: 'auth', label: 'Auth', size: 8, colorIndex: 1 },
{ id: 'users', label: 'Users', size: 10, colorIndex: 2 },
{ id: 'orders', label: 'Orders', size: 11, colorIndex: 3 },
{ id: 'payments', label: 'Payments', size: 10, colorIndex: 4 },
{ id: 'inventory', label: 'Inventory', size: 9, colorIndex: 5 },
{ id: 'notif', label: 'Notify', size: 7, colorIndex: 6 },
];
const edges = [
{ source: 'gateway', target: 'auth', weight: 4 },
{ source: 'gateway', target: 'users', weight: 5 },
{ source: 'gateway', target: 'orders', weight: 6 },
{ source: 'orders', target: 'payments', weight: 4 },
{ source: 'orders', target: 'inventory', weight: 3 },
{ source: 'payments', target: 'notif', weight: 2 },
{ source: 'orders', target: 'notif', weight: 2 },
];
</script>
<template>
<CfConnectionGraph :nodes="nodes" :edges="edges" :height="320" />
</template> <script setup>
import { CfConnectionGraph } from '@chufix-design/vue';
const nodes = [
{ id: 'gateway', label: 'Gateway', size: 12, colorIndex: 0 },
{ id: 'auth', label: 'Auth', size: 8, colorIndex: 1 },
{ id: 'users', label: 'Users', size: 10, colorIndex: 2 },
{ id: 'orders', label: 'Orders', size: 11, colorIndex: 3 },
{ id: 'payments', label: 'Payments', size: 10, colorIndex: 4 },
{ id: 'inventory', label: 'Inventory', size: 9, colorIndex: 5 },
{ id: 'notif', label: 'Notify', size: 7, colorIndex: 6 },
];
const edges = [
{ source: 'gateway', target: 'auth', weight: 4 },
{ source: 'gateway', target: 'users', weight: 5 },
{ source: 'gateway', target: 'orders', weight: 6 },
{ source: 'orders', target: 'payments', weight: 4 },
{ source: 'orders', target: 'inventory', weight: 3 },
{ source: 'payments', target: 'notif', weight: 2 },
{ source: 'orders', target: 'notif', weight: 2 },
];
</script>
<template>
<CfConnectionGraph :nodes="nodes" :edges="edges" :height="320" />
</template> import { CfConnectionGraph } from '@chufix-design/react';
export default function Demo() {
const nodes = [
{ id: 'gateway', label: 'Gateway', size: 12, colorIndex: 0 },
{ id: 'auth', label: 'Auth', size: 8, colorIndex: 1 },
{ id: 'users', label: 'Users', size: 10, colorIndex: 2 },
{ id: 'orders', label: 'Orders', size: 11, colorIndex: 3 },
{ id: 'payments', label: 'Payments', size: 10, colorIndex: 4 },
{ id: 'inventory', label: 'Inventory', size: 9, colorIndex: 5 },
{ id: 'notif', label: 'Notify', size: 7, colorIndex: 6 },
];
const edges = [
{ source: 'gateway', target: 'auth', weight: 4 },
{ source: 'gateway', target: 'users', weight: 5 },
{ source: 'gateway', target: 'orders', weight: 6 },
{ source: 'orders', target: 'payments', weight: 4 },
{ source: 'orders', target: 'inventory', weight: 3 },
{ source: 'payments', target: 'notif', weight: 2 },
{ source: 'orders', target: 'notif', weight: 2 },
];
return (
<>
<CfConnectionGraph nodes={nodes} edges={edges} />
</>
);
} import { CfConnectionGraph } from '@chufix-design/react';
export default function Demo() {
const nodes = [
{ id: 'gateway', label: 'Gateway', size: 12, colorIndex: 0 },
{ id: 'auth', label: 'Auth', size: 8, colorIndex: 1 },
{ id: 'users', label: 'Users', size: 10, colorIndex: 2 },
{ id: 'orders', label: 'Orders', size: 11, colorIndex: 3 },
{ id: 'payments', label: 'Payments', size: 10, colorIndex: 4 },
{ id: 'inventory', label: 'Inventory', size: 9, colorIndex: 5 },
{ id: 'notif', label: 'Notify', size: 7, colorIndex: 6 },
];
const edges = [
{ source: 'gateway', target: 'auth', weight: 4 },
{ source: 'gateway', target: 'users', weight: 5 },
{ source: 'gateway', target: 'orders', weight: 6 },
{ source: 'orders', target: 'payments', weight: 4 },
{ source: 'orders', target: 'inventory', weight: 3 },
{ source: 'payments', target: 'notif', weight: 2 },
{ source: 'orders', target: 'notif', weight: 2 },
];
return (
<>
<CfConnectionGraph nodes={nodes} edges={edges} />
</>
);
} API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
nodes | GraphNode[] | — | { id, label, x?, y?, colorIndex?, size? }[] |
edges | GraphEdge[] | — | { source, target, weight?, colorIndex? }[] |
width | number | 480 | SVG 宽度 |
height | number | 360 | SVG 高度 |
showLabels | boolean | true | 显示节点 label |
ariaLabel | string | — | 透传给根 <svg> 的 aria-label |
Events
| Vue 事件 | React 回调 | 载荷类型 | 说明 |
|---|---|---|---|
node-enter | onNodeEnter | ConnectionGraphNodeInteractionPayload | 鼠标进入节点 |
node-leave | onNodeLeave | ConnectionGraphNodeInteractionPayload | 鼠标离开节点 |
edge-enter | onEdgeEnter | ConnectionGraphEdgeInteractionPayload | 鼠标进入边 |
edge-leave | onEdgeLeave | ConnectionGraphEdgeInteractionPayload | 鼠标离开边 |
类型
interface ConnectionGraphNodeInteractionPayload {
node: GraphNode;
nodeIndex: number;
nativeEvent?: PointerEvent;
}
interface ConnectionGraphEdgeInteractionPayload {
edge: GraphEdge;
edgeIndex: number;
nativeEvent?: PointerEvent;
}
反馈与讨论
ConnectionGraph 连接图 的讨论