yhsz_cpts
v1.8.4
Published

Maintainers
Readme
一,LinkReview 自动布局拓扑组件
完整功能

- html
<LinkReview
graphTitle="链路图总览"
:showToolBar="false"
timeRange=" 2025-01-27 00:00:00 至 2025-01-27 24:00:00"
:graphData="graphData"
:playData="playData"
:showTimeline="true"
:statusMap="statusMap"
:timelineData="timelineData"
@singleSwitchChange="handleSingleSwitchChange"
@nodeClick="handleNodeClick"
warningStatus="important"
>
</LinkReview>- ts script
// 定义的statusMap的key需要和节点数据中的status一致,否则不会显示对应状态颜色
const statusMap = {
normal: { label: "正常", color: "#02E53D" },
important: { label: "重要", color: "#ED3939" },
emergency: { label: "紧急", color: "#FF9D00" },
minor: { label: "次要", color: "#FFE100" },
};
const graphData =
ref <
any >
{
nodes: [
{
id: "0",
label: "node-0",
status: "emergency",
tooltip: [
// 鼠标覆盖节点展示的tooltip数据
{
label: "平均时延(ms)",
value: "23",
},
{
label: "平均重连率(%)",
value: "2",
status: "emergency",
},
{
label: "平均丢包率(%)",
value: "1.5",
},
{
label: "平均响应时间(ms)",
value: "12ms",
},
],
},
{ id: "1", label: "node-1", status: "important" },
{ id: "2", label: "node-2", status: "normal" },
{ id: "3", label: "node-3", status: "minor" },
{ id: "4", label: "node-4", status: "info" },
{ id: "5", label: "node-5" },
{ id: "6", label: "node-6" },
{ id: "7", label: "node-7" },
{ id: "8", label: "node-8" },
{ id: "9", label: "node-9" },
],
edges: [
{
id: "0-1",
source: "0",
target: "1",
},
{ id: "1-4", source: "1", target: "4", desc: "238/22ms\n边数据" }, //desc为边的描述数据,可添加换行符
{
id: "0-3",
source: "0",
target: "3",
status: "important",
desc: "238/22ms",
},
{ id: "3-4", source: "3", target: "4" },
{ id: "4-5", source: "4", target: "5" },
{ id: "6-4", source: "6", target: "4" },
{ id: "4-6", source: "4", target: "6" },
{ id: "5-7", source: "5", target: "7" },
{ id: "5-8", source: "5", target: "8" },
{ id: "8-9", source: "8", target: "9" },
{ id: "2-9", source: "2", target: "9" },
{ id: "4-9", source: "3", target: "9" },
],
};
// 播放数据,播放时需要传入时间戳和对应时间戳的边数组
const playData = ref({
1672531200123: [
{ id: "0-1", source: "0", target: "1" },
{ id: "1-4", source: "1", target: "4" },
],
1672531200456: [
{ id: "6-4", source: "6", target: "4" },
{ id: "4-5", source: "4", target: "5" },
],
});
// 时间轴数据,要播放对应边需要timestamp字段与playData中的timestamp一致
const timelineData =
ref <
any >
[
{ timestamp: 1672531200123, errorNumber: 10, label: "01:00" },
{ timestamp: 1672531200456, errorNumber: 0, label: "02:00" },
{ timestamp: 1672531200789, errorNumber: 300, label: "03:00" },
{ timestamp: 1672531201123, errorNumber: 0, label: "04:00" },
{ timestamp: 1672531201456, errorNumber: 400, label: "05:00" },
{ timestamp: 1672531201789, errorNumber: 0, label: "06:00" },
{ timestamp: 1672531202123, errorNumber: 0, label: "07:00" },
{ timestamp: 1672531202456, errorNumber: 0, label: "08:00" },
{ timestamp: 1672531202789, errorNumber: 0, label: "09:00" },
{ timestamp: 1672531203123, errorNumber: 900, label: "10:00" },
];
const handleNodeClick = (v: any) => {
//do something 如点击节点弹出表格
};
const handleSingleSwitchChange = (v: boolean) => {
// 更新graph数据 or do something
console.log("孤立点switch change =", v);
// 比如说去除node-2节点
if (v == false) {
graphData.value.nodes = graphData.value.nodes.filter(
(node: any) => node.id !== "2"
);
graphData.value.edges = graphData.value.edges.filter(
(edge: any) => edge.source !== "2" && edge.target !== "2"
);
} else {
// 添加节点和连线最好对属性直接赋值。而不是分别修改nodes和edges,这样会导致渲染多次图表,还可能会导致节点位置渲染不正确
graphData.value = {
nodes: [
{
id: "0",
label: "node-0",
status: "emergency",
tooltip: [
{
label: "平均时延(ms)",
value: "23",
},
{
label: "平均重连率(%)",
value: "2",
status: "emergency",
},
{
label: "平均丢包率(%)",
value: "1.5",
},
{
label: "平均响应时间(ms)",
value: "12ms",
},
],
},
{ id: "1", label: "node-1", status: "important" },
{ id: "2", label: "node-2", status: "normal" },
{ id: "3", label: "node-3", status: "minor" },
{ id: "4", label: "node-4", status: "info" },
{ id: "5", label: "node-5" },
{ id: "6", label: "node-6" },
{ id: "7", label: "node-7" },
{ id: "8", label: "node-8" },
{ id: "9", label: "node-9" },
],
edges: [
{
id: "0-1",
source: "0",
target: "1",
},
{ id: "1-4", source: "1", target: "4", desc: "238/22ms\n边数据" },
{
id: "0-3",
source: "0",
target: "3",
status: "important",
desc: "238/22ms",
},
{ id: "3-4", source: "3", target: "4" },
{ id: "4-5", source: "4", target: "5" },
{ id: "6-4", source: "6", target: "4" },
{ id: "4-6", source: "4", target: "6" },
{ id: "5-7", source: "5", target: "7" },
{ id: "5-8", source: "5", target: "8" },
{ id: "8-9", source: "8", target: "9" },
{ id: "2-9", source: "2", target: "9" },
{ id: "4-9", source: "3", target: "9" },
],
};
}
};LinkReview API
Attributes
| 名称 | 说明 | 类型 | 默认值 | 是否必须 |
| --------------- | ------------------------------- | --------------- | ----------------------------------------------- | -------- |
| graphTitle | 标题 | string | 链路图总览 | 否 |
| showToolBar | 上方工具栏显隐 | boolean | true | 否 |
| timeRange | 上方时间文本 | string | | 否 |
| `graphData` | 拓扑图所需数据,edges、nodes 等 | `object` | `[10, 20, 30, 40, 50, 100, 200, 300, 400, 500]` | 是 |
| `playData` | 播放数据 | `object` | `{}` | 否 |
| `showTimeline` | 播放时间轴显隐 | `boolean` | `true` | 否 |
| `timelineData` | 时间轴数据 | `Array<object>` | `[]` | 否 |
| `statusMap` | 右下角 legend | `object` | `{}` | 否 |
| `warningStatus` | 左上方的 warning 图标;与定义的statusMap的key对应才能展示对应颜色 | `string` | | 否 |
Events
| 名称 | 说明 | 类型 |
| ----------------------- | ----------------------- | ---------- |
| singleSwitchChange | 切换孤立点 switch 触发 | function |
| startNodeSwitchChange | 切换开始节点 switch 触发 | function |
| nodeClick | 点击节点触发 | function |
二,TopoDesigner 拓扑编辑器
设计器模式

<TopoDesigner ref="topoRef" :preview="previewMode"> </TopoDesigner>锁定节点模式
- 此模式下,节点位置、点击节点与边展示在右侧抽屉的属性均不能改变,只能拖动画布、查看属性等。

<TopoDesigner ref="topoRef" :lock="true" />预览模式
- 与锁定模式功能类似,只是为了和系统风格统一修改了部分样式

<TopoDesigner ref="topoRef" :preview="true" />
- html
<TopoDesigner ref="topoRef" /> - ts script
// 定义TopoDesigner的ref引用
const topoRef = ref();
// 获取数据
topoRef.value?.getData();
// 设置数据(具体数据的格式可以自己拖出来一个拓扑,然后调取getGraphData控制台打印一下);网络建模模块的数据存取我是放在了`DuKang`接口数据中的nodes数组中第一个元素的nodeStyle中了(nodes?.[0]?.nodeStyle),具体见itSystemModeling/networkModeling/detail.vue
topoRef.value?.setData(JSON.parse(data));
// 清空数据
topoRef.value?.setData([]);
// 获取当前antv x6的Graph实例;获取到了实例就可以参考官网API,做一些自定义的操作
topoRef.value?.getInstance();三,LinkOverview 链路总览组件
主要用于业务监控和业务总体分析模块使用;相当于由上文中的TopoDesigner与LinkReview拼接而成;由于业务需求,网络拓扑需要用户手动拖拉拽创建,所以左侧基于antv x6开发;右侧需要根据接口数据自动排布,所以基于antv g6开发。
最开始的版本右侧是折线模式,后来由于节点与线数据可能会出现过于复杂的情况,会导致各节点之间连线有重合部分导致效果不好,之后根据产品意见改为了曲线形式
基本功能

- html
<LinkOverview
:graphTitle="`链路图总览`"
:timeRange="` 2025-01-27 00:00:00 至 2025-01-27 24:00:00`"
:networkProps="{
graphData: testData,
}"
:appProps="{
graphData: testData2,
statusMap: statusMap,
warningStatus:'important'
}"
@networkSingleSwitchChange="
(val) => {
console.log('networkSingleSwitchChange', val);
}
"
@appSingleSwitchChange="
(val) => {
console.log('appSingleSwitchChange', val);
}
"
@appStartNodeSwitchChange="
(val) => {
console.log('appStartNodeSwitchChange', val);
}
"
@appNodeClick="handleAppNodeClick"
@networkNodeClick="handleNetworkNodeClick"
@networkEdgeClick="handleNetworkEdgeClick"
@appContextClick="handleAppContextClick"
ref="topoRef"
></LinkOverview>
- ts script
// 由于拖拉拽生成的网络拓扑,所以数据中包含位置信息节点图标等信息较复杂,不用太关注具体的数据内容,拖拉拽保存的拓扑数据,从接口中取出直接再赋给组件即可渲染出对应拓扑;
const testData = ref(
[{"position":{"x":207,"y":120},"size":{"width":60,"height":80},"view":"html-view","shape":"customNode","id":"0744cc09-efd2-4347-bf0a-381e37c68f1e","data":{"label":"交换机","img":"data:image/svg+xml,%3csvg%20width='34'%20height='34'%20viewBox='0%200%2034%2034'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20id='&%23230;&%23177;&%23135;&%23232;&%23129;&%23154;&%23228;&%23186;&%23164;&%23230;&%23141;&%23162;&%23230;&%23156;&%23186;'%3e%3cpath%20id='&%23230;&%23177;&%23135;&%23232;&%23129;&%23154;&%23228;&%23186;&%23164;&%23230;&%23141;&%23162;&%23230;&%23156;&%23186;_2'%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M17%2031.875C25.2152%2031.875%2031.875%2025.2152%2031.875%2017C31.875%208.78477%2025.2152%202.125%2017%202.125C8.78476%202.125%202.125%208.78477%202.125%2017C2.125%2025.2152%208.78476%2031.875%2017%2031.875ZM17%2034C26.3888%2034%2034%2026.3888%2034%2017C34%207.61116%2026.3888%200%2017%200C7.61117%200%200%207.61116%200%2017C0%2026.3888%207.61117%2034%2017%2034ZM9.91667%2014.875H15.9375C16.1331%2014.875%2016.2917%2015.0336%2016.2917%2015.2292V17.3542C16.2917%2017.5498%2016.1331%2017.7083%2015.9375%2017.7083H9.91667V18.867C9.91667%2019.0792%209.6559%2019.2004%209.47318%2019.073L5.77754%2016.4977C5.6297%2016.3947%205.6297%2016.1887%205.77754%2016.0856L9.47318%2013.5103C9.6559%2013.383%209.91667%2013.5041%209.91667%2013.7163V14.875ZM15.9375%2021.25H9.91667V20.0913C9.91667%2019.8791%209.6559%2019.758%209.47318%2019.8853L5.77754%2022.4606C5.6297%2022.5637%205.6297%2022.7697%205.77754%2022.8727L9.47318%2025.448C9.6559%2025.5754%209.91667%2025.4542%209.91667%2025.242V24.0833H15.9375C16.1331%2024.0833%2016.2917%2023.9248%2016.2917%2023.7292V21.6042C16.2917%2021.4086%2016.1331%2021.25%2015.9375%2021.25ZM24.0833%209.91667H18.0625C17.8669%209.91667%2017.7083%2010.0752%2017.7083%2010.2708V12.3958C17.7083%2012.5914%2017.8669%2012.75%2018.0625%2012.75H24.0833V13.9087C24.0833%2014.1209%2024.3441%2014.242%2024.5268%2014.1147L28.2225%2011.5394C28.3703%2011.4363%2028.3703%2011.2303%2028.2225%2011.1273L24.5268%208.55198C24.3441%208.42464%2024.0833%208.54578%2024.0833%208.75801V9.91667ZM18.0625%2016.2917H24.0833V15.133C24.0833%2014.9208%2024.3441%2014.7996%2024.5268%2014.927L28.2225%2017.5023C28.3703%2017.6053%2028.3703%2017.8113%2028.2225%2017.9144L24.5268%2020.4897C24.3441%2020.617%2024.0833%2020.4959%2024.0833%2020.2837V19.125H18.0625C17.8669%2019.125%2017.7083%2018.9664%2017.7083%2018.7708V16.6458C17.7083%2016.4502%2017.8669%2016.2917%2018.0625%2016.2917Z'%20fill='%230099FF'/%3e%3c/g%3e%3c/svg%3e","type":"exchanger"},"ports":{"groups":{"top":{"position":[30,2],"attrs":{"circle":{"r":4,"magnet":true,"stroke":"#5F95FF","strokeWidth":1,"fill":"#fff","style":{"visibility":"hidden"}}}},"right":{"position":[60,40],"attrs":{"circle":{"r":4,"magnet":true,"stroke":"#5F95FF","strokeWidth":1,"fill":"#fff","style":{"visibility":"hidden"}}}},"bottom":{"position":[30,80],"attrs":{"circle":{"r":4,"magnet":true,"stroke":"#5F95FF","strokeWidth":1,"fill":"#fff","style":{"visibility":"hidden"}}}},"left":{"position":[0,40],"attrs":{"circle":{"r":4,"magnet":true,"stroke":"#5F95FF","strokeWidth":1,"fill":"#fff","style":{"visibility":"hidden"}}}}},"items":[{"group":"top","id":"6109329e-414d-44c6-98fd-4f90f47024e6","attrs":{"circle":{"style":{"visibility":"hidden"}}}},{"group":"right","id":"a8dea5bd-fb83-43d6-bd93-4e3cec26d5a4","attrs":{"circle":{"style":{"visibility":"hidden"}}}},{"group":"bottom","id":"1665bbcf-ea4a-40e1-93ad-0d0145866931","attrs":{"circle":{"style":{"visibility":"hidden"}}}},{"group":"left","id":"ca13963e-faf2-4de8-b19b-56d2e02c1f04","attrs":{"circle":{"style":{"visibility":"hidden"}}}}]},"zIndex":1},{"position":{"x":539,"y":271},"size":{"width":60,"height":80},"view":"html-view","shape":"customNode","id":"3fcaa3b0-4a4b-4372-a3eb-aceef4964c0f","data":{"label":"路由器","img":"data:image/svg+xml,%3csvg%20width='34'%20height='34'%20viewBox='0%200%2034%2034'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20id='&%23232;&%23183;&%23175;&%23231;&%23148;&%23177;&%23229;&%23153;&%23168;'%3e%3cpath%20id='&%23232;&%23183;&%23175;&%23231;&%23148;&%23177;&%23229;&%23153;&%23168;_2'%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M17%2031.875C25.2152%2031.875%2031.875%2025.2152%2031.875%2017C31.875%208.78477%2025.2152%202.125%2017%202.125C8.78478%202.125%202.125%208.78477%202.125%2017C2.125%2025.2152%208.78478%2031.875%2017%2031.875ZM17%2034C26.3888%2034%2034%2026.3888%2034%2017C34%207.61116%2026.3888%200%2017%200C7.61117%200%200%207.61116%200%2017C0%2026.3888%207.61117%2034%2017%2034ZM11.0909%2020.9043L13.8457%2018.1495C13.984%2018.0112%2014.2083%2018.0112%2014.3466%2018.1495L15.8492%2019.6521C15.9875%2019.7904%2015.9875%2020.0147%2015.8492%2020.153L13.0944%2022.9078L13.9137%2023.7271C14.0637%2023.8772%2013.965%2024.1472%2013.7458%2024.1864L9.31153%2024.9786C9.13414%2025.0103%208.98849%2024.8646%209.02014%2024.6872L9.81234%2020.253C9.85151%2020.0337%2010.1215%2019.935%2010.2716%2020.085L11.0909%2020.9043ZM22.9104%2013.0938L20.1556%2015.8486C20.0173%2015.9869%2019.793%2015.9869%2019.6547%2015.8486L18.1521%2014.346C18.0138%2014.2077%2018.0138%2013.9834%2018.1521%2013.8451L20.9069%2011.0903L20.0876%2010.271C19.9375%2010.1209%2020.0363%209.85087%2020.2555%209.81171L24.6898%209.01951C24.8671%208.98783%2025.0128%209.13351%2024.9811%209.31088L24.189%2013.7451C24.1498%2013.9644%2023.8797%2014.0631%2023.7297%2013.913L22.9104%2013.0938ZM22.9076%2020.9078L25.6624%2023.6625C25.8007%2023.8008%2025.8007%2024.0251%2025.6624%2024.1634L24.1598%2025.666C24.0215%2025.8043%2023.7972%2025.8043%2023.6589%2025.666L20.9041%2022.9112L20.0855%2023.7305C19.9354%2023.8806%2019.6654%2023.7819%2019.6262%2023.5626L18.834%2019.1284C18.8023%2018.951%2018.948%2018.8053%2019.1254%2018.837L23.5596%2019.6292C23.7789%2019.6684%2023.8776%2019.9384%2023.7276%2020.0885L22.9076%2020.9078ZM11.0903%2013.0938L8.3355%2010.339C8.19719%2010.2007%208.19719%209.97647%208.3355%209.83815L9.83811%208.33555C9.97641%208.19724%2010.2007%208.19724%2010.339%208.33555L13.0937%2011.0903L13.9131%2010.271C14.0631%2010.121%2014.3332%2010.2197%2014.3723%2010.4389L15.1645%2014.8732C15.1962%2015.0505%2015.0505%2015.1962%2014.8731%2015.1645L10.4389%2014.3724C10.2196%2014.3332%2010.1209%2014.0632%2010.271%2013.9131L11.0903%2013.0938Z'%20fill='%230099FF'/%3e%3c/g%3e%3c/svg%3e","type":"router"},"ports":{"groups":{"top":{"position":[30,2],"attrs":{"circle":{"r":4,"magnet":true,"stroke":"#5F95FF","strokeWidth":1,"fill":"#fff","style":{"visibility":"hidden"}}}},"right":{"position":[60,40],"attrs":{"circle":{"r":4,"magnet":true,"stroke":"#5F95FF","strokeWidth":1,"fill":"#fff","style":{"visibility":"hidden"}}}},"bottom":{"position":[30,80],"attrs":{"circle":{"r":4,"magnet":true,"stroke":"#5F95FF","strokeWidth":1,"fill":"#fff","style":{"visibility":"hidden"}}}},"left":{"position":[0,40],"attrs":{"circle":{"r":4,"magnet":true,"stroke":"#5F95FF","strokeWidth":1,"fill":"#fff","style":{"visibility":"hidden"}}}}},"items":[{"group":"top","id":"f3ead02f-8e1d-4b30-845d-1868f849a700","attrs":{"circle":{"style":{"visibility":"hidden"}}}},{"group":"right","id":"c7affd20-5d4c-45cd-8b2f-2c530ccbf97a","attrs":{"circle":{"style":{"visibility":"hidden"}}}},{"group":"bottom","id":"95f28829-f6b4-49e3-9524-fc473645409b","attrs":{"circle":{"style":{"visibility":"hidden"}}}},{"group":"left","id":"fd23e228-7bc8-4f7d-a26a-a3b05bac1e23","attrs":{"circle":{"style":{"visibility":"hidden"}}}}]},"zIndex":2},{"shape":"edge","connector":{"name":"jumpover","args":{"type":"gap"}},"router":{"name":"manhattan","args":{"padding":50}},"id":"bcda4b5d-6603-45ee-9568-5e881869a132","source":{"cell":"0744cc09-efd2-4347-bf0a-381e37c68f1e","port":"1665bbcf-ea4a-40e1-93ad-0d0145866931"},"target":{"cell":"3fcaa3b0-4a4b-4372-a3eb-aceef4964c0f","port":"95f28829-f6b4-49e3-9524-fc473645409b"},"zIndex":3}]
)
const testData2 = ref({
nodes: [
{ id: "0", label: "开始", status: "normal", tooltip: [] },
{
nodeCode: "app-3",
nodeName: "用户认证应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-3",
label: "用户认证应用",
status: "emergency",
tooltip: [
{ label: "平均时延(ms)", value: 259 },
{ label: "错误数", value: 3 },
{ label: "请求数", value: 93 },
],
},
{
nodeCode: "app-2",
nodeName: "支付网关应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-2",
label: "支付网关应用",
status: "emergency",
//新增了一个告警图标,在节点的右下侧一个三角形的warning,使用方法同status,展现形式见下图
warningStatus:'important',
tooltip: [
{ label: "平均时延(ms)", value: 502 },
{ label: "错误数", value: 6 },
{ label: "请求数", value: 148 },
],
},
{
nodeCode: "app-4",
nodeName: "订单处理应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-4",
label: "订单处理应用",
status: "emergency",
tooltip: [
{ label: "平均时延(ms)", value: 280 },
{ label: "错误数", value: 3 },
{ label: "请求数", value: 104 },
],
},
{
nodeCode: "app-5",
nodeName: "内容管理应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-5",
label: "内容管理应用",
status: "emergency",
tooltip: [
{ label: "平均时延(ms)", value: 282 },
{ label: "错误数", value: 5 },
{ label: "请求数", value: 83 },
],
},
],
edges: [
{
sourceCode: "app-4",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-4-app-3",
source: "app-4",
target: "app-3",
desc: "请求数:31/平均响应时间:244",
},
{
sourceCode: "app-2",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-2-app-3",
source: "app-2",
target: "app-3",
desc: "请求数:43/平均响应时间:278",
},
{
sourceCode: "0",
targetCode: "app-2",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "0-app-2",
source: "0",
target: "app-2",
desc: "请求数:148/平均响应时间:502",
},
{
sourceCode: "app-5",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-5-app-4",
source: "app-5",
target: "app-4",
desc: "请求数:30/平均响应时间:254",
},
{
sourceCode: "app-5",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-5-app-3",
source: "app-5",
target: "app-3",
desc: "请求数:19/平均响应时间:239",
},
{
sourceCode: "app-3",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-3-app-4",
source: "app-3",
target: "app-4",
desc: "请求数:36/平均响应时间:310",
},
{
sourceCode: "app-2",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-2-app-5",
source: "app-2",
target: "app-5",
desc: "请求数:30/平均响应时间:274",
},
{
sourceCode: "app-4",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-4-app-5",
source: "app-4",
target: "app-5",
desc: "请求数:27/平均响应时间:299",
},
{
sourceCode: "app-2",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-2-app-4",
source: "app-2",
target: "app-4",
desc: "请求数:38/平均响应时间:273",
},
{
sourceCode: "app-3",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-3-app-5",
source: "app-3",
target: "app-5",
desc: "请求数:26/平均响应时间:275",
},
],
})
const statusMap = {
normal: { label: "正常", color: "#02E53D" },
important: { label: "重要", color: "#ED3939" },
emergency: { label: "紧急", color: "#FF9D00" },
minor: { label: "次要", color: "#FFE100" },
};
const handleNetworkNodeClick = (node:any)=>{
// 网络拓扑基于antv X6,所以与应用拓扑antv g6的数据格式不同
// 节点的数据配置参数在node.store.data
console.log(`output->node`,node)
}
const handleNetworkEdgeClick = (edge:any)=>{
console.log(`output->edge`,edge)
}
const handleAppContextClick = (value:any)=>{
console.log(`output->value`, value);
}
const handleAppNodeClick = (node:any)=>{
console.log(`output->node`,node)
}
右侧应用拓扑新增了节点上的告警图标,在节点的右下侧一个三角形的warning,使用方法同status。展现形式见下图

- ts script
// 对应的节点数据:
{
nodeCode: "app-2",
nodeName: "支付网关应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-2",
label: "支付网关应用",
status: "emergency",
//新增了一个告警图标,在节点的右下侧一个三角形的warning,使用方法同status,展现形式见下图
warningStatus:'important',
tooltip: [
{ label: "平均时延(ms)", value: 502 },
{ label: "错误数", value: 6 },
{ label: "请求数", value: 148 },
],
},网络拓扑的节点鼠标覆盖展示tooltip、异常节点label左侧的红色圆点、线上的描述信息与边的状态展示。展现形式见下图

- html
<LinkOverview
...
:networkProps="{
graphData: testData,
statusMap,
nodeMetrics,
edgeMetrics,
}"
...
></LinkOverview>
- ts script
const statusMap = ref<any>({
normal: { label: "正常", color: "#02E53D" },
important: { label: "重要", color: "#ED3939" },
emergency: { label: "紧急", color: "#FF9D00" },
minor: { label: "次要", color: "#FFE100" },
});
// 与接口(http://172.17.201.11:18340/doc.html#/link_analysis-1.0.0-HTTP/%E9%93%BE%E8%B7%AF%E6%8B%93%E6%89%91%E5%88%86%E6%9E%90%E6%8E%A5%E5%8F%A3/getNetworkTopologyMetricsUsingGET)中返回的字段相同,只在edgeMetrics中新增了两个自定义字段;
// 需要注意的是,要先获取grahphData之后再获取nodeMetrics和edgeMetrics
const nodeMetrics = ref<any>([
{
nodeCode: "5c50b7b5-8e7f-435c-a1d3-406cb357a578",
avgDelay: "10", // 平均时延(ms)
avgPacketLossRate: "30", //平均丢包率(%)
avgResponseTime: "40", // 平均响应时间(ms)
avgRetransmissionRate: "20", //平均重传率(%)
hasAlarm: 1,
},
]);
const edgeMetrics = ref<any>([
{
sourceCode: "361f2c00-9c51-42f0-a0cd-c3531a8c3bbe",
targetCode: "b1263827-88ec-4094-b284-bb5eb17c770f",
packetCount: "0",
avgResponseTime: "0",
alarmStatus: 1,
// 只在接口返回数据的基础上加了以下两个字段:
desc: "20ms", //边上的文字描述
status: "important", //状态,以边上的圆点形式展示,与statusMap,同之前用法
},
]);⚠️250515新需求:应用拓扑新增筛选功能
- 效果

- html
<LinkOverview
...
:appProps="{
linkOptions,
warningStatus: 'important',
warningText: '紧急警告!',
defaultSelectedLinks:['1'] //下拉默认值
...
}"
@appLinkSelectChange = 'appLinkSelectChange'
...
></LinkOverview>
- ts script
const linkOptions = ref([
{
label: "test1",
value: "1",
status: "important",//与statusMap映射,同之前用法
},
{ label: "test2", value: "2" },
{ label: "test3", value: "3" },
{ label: "test4", value: "4" },
{ label: "test5", value: "5" },
{ label: "test6", value: "6" },
{ label: "test7", value: "7" },
{ label: "test8", value: "8" },
{ label: "test9", value: "9" },
{ label: "test10", value: "10" },
{ label: "test11", value: "11" },
]);
const appLinkSelectChange = (selectIds: string[]) => {
console.log("selectIds", selectIds);
// 在此根据筛选结果对数据进行过滤or other operations,然后对拓扑重新赋值即可
};⚠️250611新需求:
1,网络拓扑-网络节点图标标红功能,线标红,线描述标红
2,网络拓扑-主机告警列表contextMenu
3,应用拓扑-节点标红功能、主机告警、应用告警功能
4,应用拓扑-主机告警列表、应用告警列表contextMenu
效果

网络拓扑 代码示例
- html
<LinkOverview
...
:networkProps="{
graphData: testData,
statusMap,
nodeMetrics,
edgeMetrics,
}"
@netContextClick="handleNetContextClick" //右键点击事件
...
></LinkOverview>
- ts script
const statusMap = ref<any>({
normal: { label: "正常", color: "#02E53D" },
important: { label: "重要", color: "#ED3939" },
emergency: { label: "紧急", color: "#FF9D00" },
minor: { label: "次要", color: "#FFE100" },
});
// 与接口(http://172.17.201.11:18340/doc.html#/link_analysis-1.0.0-HTTP/%E9%93%BE%E8%B7%AF%E6%8B%93%E6%89%91%E5%88%86%E6%9E%90%E6%8E%A5%E5%8F%A3/getNetworkTopologyMetricsUsingGET)中返回的字段相同,只在edgeMetrics中新增了两个自定义字段;
// 需要注意的是,要先获取grahphData之后再获取nodeMetrics和edgeMetrics
const nodeMetrics = ref<any>([
{
nodeCode: "5c50b7b5-8e7f-435c-a1d3-406cb357a578",
avgDelay: "10", // 平均时延(ms)
avgPacketLossRate: "30", //平均丢包率(%)
avgResponseTime: "40", // 平均响应时间(ms)
avgRetransmissionRate: "20", //平均重传率(%)
hasAlarm: 1, //节点标红
tooltip: [//节点鼠标覆盖展示tooltip
{ label: "主机ip: ", value: "241.00" },
{ label: "内存使用率(%): ", value: 6 },
{ label: "CPU使用率(%): ", value: 332 },
{ label: "磁盘使用率(%): ", value: "1.81" },
],
},
]);
const edgeMetrics = ref<any>([
{
sourceCode: "361f2c00-9c51-42f0-a0cd-c3531a8c3bbe",
targetCode: "b1263827-88ec-4094-b284-bb5eb17c770f",
packetCount: "0",
avgResponseTime: "0",
alarmStatus: 1,
// 只在接口返回数据的基础上加了以下两个字段:
desc: "20ms", //边上的文字描述
warning: 1, //1是0否 1时线、描述标红
},
]);应用拓扑 代码示例
右键事件同之前用法
ts script
// 对应的节点数据:
{
nodeCode: "app-5",
nodeName: "内容管理应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-5",
label: "内容管理应用",
nodeWarning: true, //节点标红 1/true
hostWarning: true,//主机告警 1/true
appWarning: true,//应用告警 1/true
tooltip: [
{ label: "平均响应时间(ms): ", value: "241.00" },
{ label: "请求错误数: ", value: 6 },
{ label: "请求数: ", value: 332 },
{ label: "请求错误率(%): ", value: "1.81" },
{ label: "耗时(ms): ", value: "241.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
LinkOverview API
Attributes
| 名称 | 说明 | 类型 | 默认值 | 是否必须 |
| --------------- | ------------------------------- | --------------- | ----------------------------------------------- | -------- |
| graphTitle | 标题 | string | 链路图总览 | 否 |
| timeRange | 上方时间文本 | string | | 否 |
| `networkProps.graphData` | 网络拓扑图所需数据 | `Array<object>` | `[]` | 是 |
| `networkProps.statusMap` | 节点状态、边状态的枚举 | `object` | `{}` | 否 |
| `networkProps.nodeMetrics` | 网络拓扑图节点指标 | `Array<object>` | `[]` | 否 |
| `networkProps.edgeMetrics` | 网络拓扑图边指标 | `Array<object>` | `[]` | 否 |
| `networkProps.hidden` | 是否隐藏网络拓扑图 | `boolean` | `false` | 否 |
| `appProps.graphData` | 应用拓扑图所需数据 | `object` | `{}` | 是 |
| `appProps.statusMap` | legend枚举,为了和warningStatus字段做映射 | `object` | `{}` | 否 |
| `appProps.warningStatus` | 左上方的 warning 图标;与定义的statusMap的key对应才能展示对应颜色 | `string` | | 否 |
| appProps.hidden | 是否隐藏应用拓扑图 | boolean | false | 否 |
| appProps.linkOptions | 应用拓扑下拉搜索选项 | Array<object> | false | 否 |
| appProps.warningText | 左上方的 warning 文本 | string | false | 否 |
| appProps.defaultSelectedLinks | 链路筛选默认值 | string[] | false
| appProps.loading | 右侧拓扑loading | false | false
| networkProps.loading | 左侧拓扑loading | false | false
Events
| 名称 | 说明 | 类型 |
| ----------------------- | ----------------------- | ---------- |
| networkSingleSwitchChange、appSingleSwitchChange | 切换孤立点 switch 触发 | function |
| appStartNodeSwitchChange | 切换开始节点 switch 触发 | function |
| appNodeClick、networkNodeClick | 点击节点触发 | function |
| appContextClick | 应用拓扑右键节点触发 | function |
| netContextClick | 网络拓扑右键节点触发 | function |
| networkEdgeClick | 点击边触发 | function |
| appLinkSelectChange | 应用拓扑搜索链路=》切换checkbox触发 | function |
四,GlobalLinkReview 全局链路组件
⚠️250619新需求:
1,修复了网络拓扑线上指标重叠的问题
2,新增组件
GlobalLinkReview2,新增线与线描述信息颜色控制
color属性效果

主要属性
nodeWarning设置之后节点是红色subLabel节点下方的子名称color属性控制线与线描述信息颜色
- html
<GlobalLinkOverview
:loading="appLoading"
:graphData="testData"
graphTitle="全局链路图总览"
@singleSwitchChange='()=>{}'
@nodeClick='()=>{}'
/>- ts script
const testData = {
nodes: [
{
id: "0",
label: "开始",
subLabel: "122/1234ms/12%",//子标题
tooltip: [],
},
{
nodeCode: "app-2",
nodeName: "支付网关应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-2",
label: "支付网关应用",
subLabel: "122/1234ms/12%",
tooltip: [
{ label: "平均响应时间(ms): ", value: "507.00" },
{ label: "请求错误数: ", value: 76 },
{ label: "请求数: ", value: 1607 },
{ label: "请求错误率(%): ", value: "4.73" },
{ label: "耗时(ms): ", value: "507.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
{
nodeCode: "app-5",
nodeName: "内容管理应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-5",
label: "内容管理应用",
subLabel: "122/1234ms/12%",
nodeWarning: true,//红色告警节点
tooltip: [
{ label: "平均响应时间(ms): ", value: "241.00" },
{ label: "请求错误数: ", value: 6 },
{ label: "请求数: ", value: 332 },
{ label: "请求错误率(%): ", value: "1.81" },
{ label: "耗时(ms): ", value: "241.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
{
nodeCode: "app-3",
nodeName: "用户认证应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-3",
label: "用户认证应用",
subLabel: "122/1234ms/12%",
tooltip: [
{ label: "平均响应时间(ms): ", value: "247.00" },
{ label: "请求错误数: ", value: 20 },
{ label: "请求数: ", value: 341 },
{ label: "请求错误率(%): ", value: "5.87" },
{ label: "耗时(ms): ", value: "247.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
{
nodeCode: "app-4",
nodeName: "订单处理应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-4",
label: "订单处理应用",
subLabel: "122/1234ms/12%",
tooltip: [
{ label: "平均响应时间(ms): ", value: "243.00" },
{ label: "请求错误数: ", value: 16 },
{ label: "请求数: ", value: 352 },
{ label: "请求错误率(%): ", value: "4.55" },
{ label: "耗时(ms): ", value: "243.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
],
edges: [
{
sourceCode: "0",
targetCode: "app-2",
color:"red",//线颜色控制
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "0-app-2",
source: "0",
target: "app-2",
desc: "1607/507.00ms",
},
{
sourceCode: "app-2",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-2-app-5",
source: "app-2",
target: "app-5",
desc: "137/257.00ms",
},
{
sourceCode: "0",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "0-app-3",
source: "0",
target: "app-3",
desc: "136/261.00ms",
},
{
sourceCode: "app-3",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-3-app-5",
source: "app-3",
target: "app-5",
desc: "27/216.00ms",
},
{
sourceCode: "app-2",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-2-app-4",
source: "app-2",
target: "app-4",
desc: "148/248.00ms",
},
{
sourceCode: "app-4",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-4-app-3",
source: "app-4",
target: "app-3",
desc: "35/231.00ms",
},
{
sourceCode: "app-2",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-2-app-3",
source: "app-2",
target: "app-3",
desc: "138/236.00ms",
},
{
sourceCode: "app-5",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-5-app-4",
source: "app-5",
target: "app-4",
desc: "21/294.00ms",
},
{
sourceCode: "0",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "0-app-5",
source: "0",
target: "app-5",
desc: "126/230.00ms",
},
{
sourceCode: "0",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "0-app-4",
source: "0",
target: "app-4",
desc: "145/247.00ms",
},
{
sourceCode: "app-5",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-5-app-3",
source: "app-5",
target: "app-3",
desc: "32/250.00ms",
},
{
sourceCode: "app-4",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-4-app-5",
source: "app-4",
target: "app-5",
desc: "42/241.00ms",
},
{
sourceCode: "app-3",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-3-app-4",
source: "app-3",
target: "app-4",
desc: "38/178.00ms",
},
],
}
⚠️250704新需求:
节点
- 新增
disabled属性,设置了此属性之后节点会变成浅灰色,并且鼠标覆盖不会有tooltip等交互
线
- 新增
activated属性,设置了此属性之后线会变成与UI一致的蓝色加粗线条,相当于设置了线条加粗+color蓝色;之前的color属性仍然可用 - 新增
lineWidth属性,可以设置edge宽度,加上上述的activated属性就已经加粗了,如果效果不满意想继续加粗可以设置lineWidth属性
- 效果

- html
<GlobalLinkOverview
:loading="appLoading"
:graphData="testData"
graphTitle="全局链路图总览"
@singleSwitchChange='()=>{}'
@nodeClick='()=>{}'
/>- ts script
const testData = {
nodes: [
{
id: "0",
label: "开始",
subLabel: "122/1234ms/12%",
tooltip: [],
},
{
nodeCode: "app-2",
nodeName: "支付网关应用",
chainType: 1,
nodeWarning: true,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-2",
label: "支付网关应用",
subLabel: "122/1234ms/12%",
tooltip: [
{ label: "平均响应时间(ms): ", value: "507.00" },
{ label: "请求错误数: ", value: 76 },
{ label: "请求数: ", value: 1607 },
{ label: "请求错误率(%): ", value: "4.73" },
{ label: "耗时(ms): ", value: "507.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
{
nodeCode: "app-5",
nodeName: "内容管理应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-5",
label: "内容管理应用",
subLabel: "122/1234ms/12%",
tooltip: [
{ label: "平均响应时间(ms): ", value: "241.00" },
{ label: "请求错误数: ", value: 6 },
{ label: "请求数: ", value: 332 },
{ label: "请求错误率(%): ", value: "1.81" },
{ label: "耗时(ms): ", value: "241.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
{
nodeCode: "app-3",
nodeName: "用户认证应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-3",
label: "用户认证应用",
subLabel: "122/1234ms/12%",
status: "emergency",
tooltip: [
{ label: "平均响应时间(ms): ", value: "247.00" },
{ label: "请求错误数: ", value: 20 },
{ label: "请求数: ", value: 341 },
{ label: "请求错误率(%): ", value: "5.87" },
{ label: "耗时(ms): ", value: "247.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
{
nodeCode: "app-4",
nodeName: "订单处理应用",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "app-4",
label: "订单处理应用",
disabled: true,
subLabel: "122/1234ms/12%",
tooltip: [
{ label: "平均响应时间(ms): ", value: "243.00" },
{ label: "请求错误数: ", value: 16 },
{ label: "请求数: ", value: 352 },
{ label: "请求错误率(%): ", value: "4.55" },
{ label: "耗时(ms): ", value: "243.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
],
edges: [
{
activated: true,
sourceCode: "0",
targetCode: "app-2",
edgeType: "ONE_WAY",
color: "red",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "0-app-2",
source: "0",
target: "app-2",
desc: "1607/507.00ms",
},
{
activated: true,
lineWidth: 2,
sourceCode: "app-2",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-2-app-5",
source: "app-2",
target: "app-5",
desc: "137/257.00ms",
},
{
sourceCode: "0",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "0-app-3",
source: "0",
target: "app-3",
desc: "136/261.00ms",
},
{
activated: true,
sourceCode: "app-3",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-3-app-5",
source: "app-3",
target: "app-5",
desc: "27/216.00ms",
},
{
sourceCode: "app-2",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-2-app-4",
source: "app-2",
target: "app-4",
desc: "148/248.00ms",
},
{
sourceCode: "app-4",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-4-app-3",
source: "app-4",
target: "app-3",
desc: "35/231.00ms",
},
{
sourceCode: "app-2",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-2-app-3",
source: "app-2",
target: "app-3",
desc: "138/236.00ms",
},
{
sourceCode: "app-5",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-5-app-4",
source: "app-5",
target: "app-4",
desc: "21/294.00ms",
},
{
sourceCode: "0",
targetCode: "app-5",
edgeType: "ONE_WAY",
activated: true,
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "0-app-5",
source: "0",
target: "app-5",
desc: "126/230.00ms",
},
{
sourceCode: "0",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "0-app-4",
source: "0",
target: "app-4",
desc: "145/247.00ms",
},
{
sourceCode: "app-5",
targetCode: "app-3",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-5-app-3",
source: "app-5",
target: "app-3",
desc: "32/250.00ms",
},
{
sourceCode: "app-4",
targetCode: "app-5",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-4-app-5",
source: "app-4",
target: "app-5",
desc: "42/241.00ms",
},
{
sourceCode: "app-3",
targetCode: "app-4",
edgeType: "ONE_WAY",
chainType: 1,
edgeConfig: null,
edgeStyle: null,
id: "app-3-app-4",
source: "app-3",
target: "app-4",
desc: "38/178.00ms",
},
],
}
五,TopoPreview 组件
⚠️251015新需求:
- 替换业务监控、业务总体分析模块的拓扑图
- 效果

- html
<TopoPreview
graphTitle="拓扑视图"
:graphData="graphData"
:nodeMetrics="nodeMetrics"
:edgeMetrics="edgeMetrics"
@ContextClick="handleContextClick"
/> - ts script
const nodeMetrics = ref<any>([
{
nodeCode: "fc488edc-97d0-4f26-9ee6-695337907d2f",
avgDelay: "10", // 平均时延(ms)
avgPacketLossRate: "30", //平均丢包率(%)
avgResponseTime: "40", // 平均响应时间(ms)
avgRetransmissionRate: "20", //平均重传率(%)
connectFailureRate: "50",
hasAlarm: 1,
nodeIp: "192.168.1.1",
tooltip: [
{ label: "平均响应时间(ms): ", value: "247.00" },
{ label: "请求错误数: ", value: 20 },
{ label: "请求数: ", value: 341 },
{ label: "请求错误率(%): ", value: "5.87" },
{ label: "耗时(ms): ", value: "247.00" },
{ label: "内存使用率(%): ", value: "0.00" },
{ label: "CPU使用率(%): ", value: "0.00" },
{ label: "磁盘使用率(%): ", value: "0.00" },
],
},
]);
const edgeMetrics = ref<any>([
{
sourceCode: "fc488edc-97d0-4f26-9ee6-695337907d2f",
targetCode: "0e5d0518-f7bc-43e9-a9ef-0cfc291bedfb",
packetCount: "0",
avgResponseTime: "0",
alarmStatus: 1,
desc: "59/14.78ms", //边上的文字描述
warning: 1,
},
{
sourceCode: "app-2",
targetCode: "app-5",
packetCount: "0",
avgResponseTime: "0",
alarmStatus: 1,
desc: "59/14.78ms", //边上的文字描述
warning: 1,
},
{
sourceCode: "19cb25b1-85ec-4fb8-92f1-c4349a6a1edf",
targetCode: "6ed954a9-d18d-4346-8fcd-4f4835cbaf82",
packetCount: "0",
avgResponseTime: "0",
alarmStatus: 1,
desc: "66/88.78ms", //边上的文字描述
warning: 1,
},
]);
const graphData = {
client: {
nodes: [
{
nodeCode: "client-0",
nodeName: "客户端",
chainType: 1,
nodeType: null,
nodeConfig: null,
nodeStyle: null,
id: "client-0",
label: "客户端",
status: "emergency",
tooltip: [
{ label: "平均时延(ms)", value: 510 },
{ label: "错误数", value: 10 },
{ label: "请求数", value: 130 },
],
},
],
edges: [
// {
// sourceCode: "client-0",
// targetCode: "fc488edc-97d0-4f26-9ee6-695337907d2f",
// id: "client-0-fc488edc-97d0-4f26-9ee6-695337907d2f",
// source: "client-0",
// target: "fc488edc-97d0-4f26-9ee6-695337907d2f",
// },
],
},
network: [
{
position: { x: 69, y: 77 },
size: { width: 60, height: 80 },
view: "html-view",
shape: "customNode",
id: "fc488edc-97d0-4f26-9ee6-695337907d2f",
data: { label: "交换机", type: "exchanger" },
ports: {
groups: {
top: {
position: [30, 2],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
right: {
position: [60, 40],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
bottom: {
position: [30, 80],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
left: {
position: [0, 40],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
},
items: [
{
group: "top",
id: "9bab0b66-9913-4868-883a-3bcd6eeb8f96",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "right",
id: "dd8cc04a-0471-423f-91d4-a08692246982",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "bottom",
id: "bc246f9c-53b6-4949-9b2a-5d964a174f77",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "left",
id: "e46ef986-ffbf-41f8-b434-8745b17e1ede",
attrs: { circle: { style: { visibility: "hidden" } } },
},
],
},
zIndex: 1,
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "9110cc0d-1af9-40cb-9a50-6c651c3ae831",
source: {
cell: "fc488edc-97d0-4f26-9ee6-695337907d2f",
port: "dd8cc04a-0471-423f-91d4-a08692246982",
},
target: {
cell: "0e5d0518-f7bc-43e9-a9ef-0cfc291bedfb",
port: "9da1902e-1b25-4525-a2dd-88da4e211deb",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "b0617dad-7669-4631-8f77-84abbbd4d26b",
source: {
cell: "fc488edc-97d0-4f26-9ee6-695337907d2f",
port: "dd8cc04a-0471-423f-91d4-a08692246982",
},
target: {
cell: "113d9869-04f3-4588-aabb-27320c7a2abf",
port: "403ad49e-5f1d-438b-a752-ec170febc0f7",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "26f3c496-b990-475f-8cda-bdd3565c07bf",
source: {
cell: "113d9869-04f3-4588-aabb-27320c7a2abf",
port: "7818e36b-98d3-49ea-9a69-965b54847d0d",
},
target: {
cell: "fd801254-5388-4951-a12c-6f9badf30b4a",
port: "fbfaad3f-0eb1-4f3c-b2d1-4fc0a516705c",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "2b57d6d9-796b-4fc5-8ca9-a1a9fe35c75a",
source: {
cell: "0e5d0518-f7bc-43e9-a9ef-0cfc291bedfb",
port: "fd92228d-ca99-4de6-93d1-32400f14bdf9",
},
target: {
cell: "f5c83e15-0e35-4309-94c4-e5849d31a0f5",
port: "d120dcc9-329c-44ba-886d-c5d224833561",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "433e97a4-8921-4ff3-b0a8-716d30694d18",
source: {
cell: "fd801254-5388-4951-a12c-6f9badf30b4a",
port: "68931aee-0eb4-43f9-8c35-fbb0910b3efc",
},
target: {
cell: "d7de6a14-064e-4ffb-95b2-5ea31f1d1347",
port: "06f819f8-a28c-4157-b145-0862db8ddafa",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "7b3bab78-4353-4826-9308-15c1b9ae5149",
source: {
cell: "fd801254-5388-4951-a12c-6f9badf30b4a",
port: "4be336b5-9150-4085-b7b4-15f3ba99dd38",
},
target: {
cell: "f305a38d-7bc8-4c95-bbd8-0d5af8dda517",
port: "7412021a-54e5-44c0-a16e-3d0a67a8482d",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "a4f89b13-ba4e-4fb5-918a-d62fe1332f4f",
source: {
cell: "f305a38d-7bc8-4c95-bbd8-0d5af8dda517",
port: "3abdad95-dfe6-4a9a-90f8-7d272eebaf9b",
},
target: {
cell: "a1ceada1-c2cc-4420-994e-5f65f669751c",
port: "f27afc81-0049-407a-bcec-97c785782308",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "eac63ef8-e6d3-49b7-8b3f-22a89462092a",
source: {
cell: "d7de6a14-064e-4ffb-95b2-5ea31f1d1347",
port: "c1c804a1-be8a-4424-bc67-381dcca9abbb",
},
target: {
cell: "a1ceada1-c2cc-4420-994e-5f65f669751c",
port: "97a7c587-8d38-4514-978f-4ba87ec33999",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "ce1e3741-a659-42c1-909f-b052629ad732",
source: {
cell: "f5c83e15-0e35-4309-94c4-e5849d31a0f5",
port: "56de6d8e-c53c-4504-a7a1-4d8fe0c136a8",
},
target: {
cell: "893f1d6a-090b-49f4-9fbd-41ff26ee2a8d",
port: "dbef3881-b344-4e84-a425-85e9927f25c1",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "b2ab824c-706d-4619-898f-520479d629cc",
source: {
cell: "f5c83e15-0e35-4309-94c4-e5849d31a0f5",
port: "56de6d8e-c53c-4504-a7a1-4d8fe0c136a8",
},
target: {
cell: "d2fba48f-b4c4-4ede-b223-193145a01eb6",
port: "886f4074-67e8-49e9-9f6e-9a262b282361",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "24a5b0e3-0f36-49d6-beda-ce2a7a50a2ec",
source: {
cell: "a1ceada1-c2cc-4420-994e-5f65f669751c",
port: "bba7a87b-7693-4711-bae6-1bb28ff08a56",
},
target: {
cell: "1ab0a099-52d1-4f61-83a8-3088acba1910",
port: "6e405a01-0087-43ef-aae5-5ca6b428beb3",
},
vertices: [],
},
{
shape: "edge",
zIndex: 1,
connector: { name: "smooth", args: { raw: false } },
id: "11c144bb-ca88-45b3-a896-d91b1a104dca",
source: {
cell: "893f1d6a-090b-49f4-9fbd-41ff26ee2a8d",
port: "62d1e64f-40d8-41e2-a342-523f07210826",
},
target: {
cell: "1ab0a099-52d1-4f61-83a8-3088acba1910",
port: "6e405a01-0087-43ef-aae5-5ca6b428beb3",
},
},
{
position: { x: 212, y: 32 },
size: { width: 60, height: 80 },
view: "html-view",
shape: "customNode",
id: "113d9869-04f3-4588-aabb-27320c7a2abf",
data: { label: "路由器", type: "router" },
ports: {
groups: {
top: {
position: [30, 2],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
right: {
position: [60, 40],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
bottom: {
position: [30, 80],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
left: {
position: [0, 40],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
},
items: [
{
group: "top",
id: "7993fd26-855e-4827-bf43-db082ba305e1",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "right",
id: "7818e36b-98d3-49ea-9a69-965b54847d0d",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "bottom",
id: "0620321f-19e3-46de-8aff-4ac1d7a0f4d0",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "left",
id: "403ad49e-5f1d-438b-a752-ec170febc0f7",
attrs: { circle: { style: { visibility: "hidden" } } },
},
],
},
zIndex: 2,
},
{
position: { x: 212, y: 139 },
size: { width: 60, height: 80 },
view: "html-view",
shape: "customNode",
id: "0e5d0518-f7bc-43e9-a9ef-0cfc291bedfb",
data: { label: "路由器", type: "router" },
ports: {
groups: {
top: {
position: [30, 2],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
right: {
position: [60, 40],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
bottom: {
position: [30, 80],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
left: {
position: [0, 40],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
},
items: [
{
group: "top",
id: "907c6461-2503-4bb9-83a5-151253585c63",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "right",
id: "c65c3e2f-8a3e-4449-ab51-4e10ee134880",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "bottom",
id: "fd92228d-ca99-4de6-93d1-32400f14bdf9",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "left",
id: "9da1902e-1b25-4525-a2dd-88da4e211deb",
attrs: { circle: { style: { visibility: "hidden" } } },
},
],
},
zIndex: 3,
},
{
position: { x: 449, y: 32 },
size: { width: 60, height: 80 },
view: "html-view",
shape: "customNode",
id: "fd801254-5388-4951-a12c-6f9badf30b4a",
data: { label: "路由器", type: "router" },
ports: {
groups: {
top: {
position: [30, 2],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
right: {
position: [60, 40],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
bottom: {
position: [30, 80],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
left: {
position: [0, 40],
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: { visibility: "hidden" },
},
},
},
},
items: [
{
group: "top",
id: "8bee0659-d0cd-45bd-9fc6-9064a586e665",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "right",
id: "68931aee-0eb4-43f9-8c35-fbb0910b3efc",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "bottom",
id: "4be336b5-9150-4085-b7b4-15f3ba99dd38",
attrs: { circle: { style: { visibility: "hidden" } } },
},
{
group: "left",
id: "fbfaad3f-0eb1-4f3c-b2d1-4fc0a516705c",
attrs: { circle: { style: { visibility: "hidden" } } },
},
],
},
zIndex: 4,
},
{
position: { x: 225, y: 423 },
size: { width: 60, height: 80 },
view: "html-view",
shape: "customNode",
id: "f5c83e15-0e35-4309-94c4-e5849d31a0f5",
data: { label: "负载均衡", type: "load_balancer" },
ports: {
groups: {
top: {
position: [30, 2],
attrs: {
circle: {
r: 4,