diff --git a/src/hooks/useEcharts.ts b/src/hooks/useEcharts.ts index 052b751e..16b505b2 100644 --- a/src/hooks/useEcharts.ts +++ b/src/hooks/useEcharts.ts @@ -19,6 +19,7 @@ import { LineSeriesOption, HeatmapSeriesOption, PieSeriesOption, + SankeySeriesOption, } from "echarts/charts"; import { TitleComponentOption, @@ -46,6 +47,7 @@ export type ECOption = echarts.ComposeOption< | LegendComponentOption | HeatmapSeriesOption | PieSeriesOption + | SankeySeriesOption >; export function useECharts( diff --git a/src/store/modules/topology.ts b/src/store/modules/topology.ts index d6dde5bc..cb7b6466 100644 --- a/src/store/modules/topology.ts +++ b/src/store/modules/topology.ts @@ -28,8 +28,8 @@ interface MetricVal { [key: string]: { values: { id: string; value: unknown }[] }; } interface TopologyState { - node: Node | null; - call: Call | null; + node: Nullable; + call: Nullable; calls: Call[]; nodes: Node[]; nodeMetrics: MetricVal; @@ -76,6 +76,43 @@ export const topologyStore = defineStore({ return c; }); }, + setInstanceTopology(data: { nodes: Node[]; calls: Call[] }) { + for (const call of data.calls) { + for (const node of data.nodes) { + if (call.source === node.id) { + call.sourceObj = node; + } + if (call.target === node.id) { + call.targetObj = node; + } + } + call.value = call.value || 1; + } + this.calls = data.calls; + this.nodes = data.nodes; + }, + setEndpointTopology(data: { nodes: Node[]; calls: Call[] }) { + const obj = {} as any; + let nodes = []; + let calls = []; + nodes = data.nodes.reduce((prev: Node[], next: Node) => { + if (!obj[next.id]) { + obj[next.id] = true; + prev.push(next); + } + return prev; + }, []); + calls = data.calls.reduce((prev: Call[], next: Call) => { + if (!obj[next.id]) { + obj[next.id] = true; + next.value = next.value || 1; + prev.push(next); + } + return prev; + }, []); + this.calls = calls; + this.nodes = nodes; + }, setNodeMetrics(m: { id: string; value: unknown }[]) { this.nodeMetrics = m; }, @@ -135,7 +172,7 @@ export const topologyStore = defineStore({ duration, }); if (!res.data.errors) { - this.setTopology(res.data.data.topology); + this.setEndpointTopology(res.data.data.topology); } return res.data; }, @@ -151,7 +188,7 @@ export const topologyStore = defineStore({ duration, }); if (!res.data.errors) { - this.setTopology(res.data.data.topology); + this.setInstanceTopology(res.data.data.topology); } return res.data; }, diff --git a/src/types/topology.d.ts b/src/types/topology.d.ts index c0e57d1b..6041a63f 100644 --- a/src/types/topology.d.ts +++ b/src/types/topology.d.ts @@ -20,7 +20,9 @@ export interface Call { id: string; detectPoints: string[]; type?: string; - layer?: string; + sourceObj?: any; + targetObj?: any; + value?: number; } export interface Node { id: string; diff --git a/src/utils/echarts.ts b/src/utils/echarts.ts index 7795e094..9103f912 100644 --- a/src/utils/echarts.ts +++ b/src/utils/echarts.ts @@ -16,7 +16,13 @@ */ import * as echarts from "echarts/core"; -import { BarChart, LineChart, PieChart, HeatmapChart } from "echarts/charts"; +import { + BarChart, + LineChart, + PieChart, + HeatmapChart, + SankeyChart, +} from "echarts/charts"; import { TitleComponent, @@ -39,6 +45,7 @@ echarts.use([ LineChart, PieChart, HeatmapChart, + SankeyChart, SVGRenderer, DataZoomComponent, VisualMapComponent, diff --git a/src/views/dashboard/Edit.vue b/src/views/dashboard/Edit.vue index 3f26b19f..42a67c99 100644 --- a/src/views/dashboard/Edit.vue +++ b/src/views/dashboard/Edit.vue @@ -32,7 +32,7 @@ limitations under the License. --> @closed="dashboardStore.setTopology(false)" custom-class="dark-dialog" > - + @@ -42,7 +42,7 @@ import GridLayout from "./panel/Layout.vue"; // import { LayoutConfig } from "@/types/dashboard"; import Tool from "./panel/Tool.vue"; import ConfigEdit from "./configuration/ConfigEdit.vue"; -import Graph from "./related/topology/Graph.vue"; +import Topology from "./related/topology/Index.vue"; import { useDashboardStore } from "@/store/modules/dashboard"; import { useAppStoreWithOut } from "@/store/modules/app"; diff --git a/src/views/dashboard/related/topology/Graph.vue b/src/views/dashboard/related/topology/Graph.vue index 80a127a6..a2814fc3 100644 --- a/src/views/dashboard/related/topology/Graph.vue +++ b/src/views/dashboard/related/topology/Graph.vue @@ -17,7 +17,7 @@ limitations under the License. --> ref="chart" class="micro-topo-chart" v-loading="loading" - :style="`height: ${height}`" + :style="`height: ${height}px`" >
@@ -182,7 +182,6 @@ function handleNodeClick(d: Node & { x: number; y: number }) { topologyStore.setLink(null); operationsPos.x = d.x; operationsPos.y = d.y + 30; - console.log(d.layer === String(dashboardStore.layerId)); if (d.layer === String(dashboardStore.layerId)) { return; } @@ -322,7 +321,9 @@ async function handleInspect() { const id = topologyStore.node.id; topologyStore.setNode(null); topologyStore.setLink(null); + loading.value = true; const resp = await topologyStore.getServiceTopology(id); + loading.value = false; if (resp.errors) { ElMessage.error(resp.errors); @@ -356,7 +357,9 @@ function handleGoAlarm() { } async function backToTopology() { svg.value.selectAll(".topo-svg-graph").remove(); + loading.value = true; const resp = await getTopology(); + loading.value = false; if (resp.errors) { ElMessage.error(resp.errors); @@ -377,12 +380,6 @@ async function getTopology() { case EntityType[1].value: resp = await topologyStore.getServicesTopology(); break; - case EntityType[2].value: - resp = await topologyStore.getEndpointTopology(); - break; - case EntityType[4].value: - resp = await topologyStore.getInstanceTopology(); - break; } return resp; } diff --git a/src/views/dashboard/related/topology/Index.vue b/src/views/dashboard/related/topology/Index.vue new file mode 100644 index 00000000..673f8926 --- /dev/null +++ b/src/views/dashboard/related/topology/Index.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/views/dashboard/related/topology/Sankey.vue b/src/views/dashboard/related/topology/Sankey.vue new file mode 100644 index 00000000..5a577095 --- /dev/null +++ b/src/views/dashboard/related/topology/Sankey.vue @@ -0,0 +1,107 @@ + + + + +