feat: enhance topology layout and fix calls metrics (#344)

This commit is contained in:
Fine0830 2023-11-23 16:37:26 +08:00 committed by GitHub
parent d8a3c27345
commit ac57b229fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 15 deletions

View File

@ -179,6 +179,7 @@ export const dashboardStore = defineStore({
newItem.graph = { newItem.graph = {
showDepth: true, showDepth: true,
}; };
newItem.metricMode = MetricModes.Expression;
} }
if (ControlsTypes.includes(type)) { if (ControlsTypes.includes(type)) {
newItem.h = 32; newItem.h = 32;

View File

@ -157,6 +157,10 @@ $active-background: var(--el-color-primary);
$font-size-smaller: 12px; $font-size-smaller: 12px;
$font-size-normal: 14px; $font-size-normal: 14px;
.opt:hover {
background-color: var(--sw-list-hover) !important;
}
.el-loading-mask { .el-loading-mask {
background-color: var(--theme-background); background-color: var(--theme-background);
} }

View File

@ -345,3 +345,7 @@ export enum MetricModes {
Expression = "Expression", Expression = "Expression",
General = "General", General = "General",
} }
export enum CallTypes {
Server = "SERVER",
Client = "CLIENT",
}

View File

@ -140,7 +140,7 @@ limitations under the License. -->
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { useTopologyStore } from "@/store/modules/topology"; import { useTopologyStore } from "@/store/modules/topology";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { EntityType, DepthList, MetricModes } from "../../../data"; import { EntityType, DepthList, MetricModes, CallTypes } from "../../../data";
import router from "@/router"; import router from "@/router";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import Settings from "./Settings.vue"; import Settings from "./Settings.vue";
@ -224,8 +224,8 @@ limitations under the License. -->
async function update() { async function update() {
if (settings.value.metricMode === MetricModes.Expression) { if (settings.value.metricMode === MetricModes.Expression) {
topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []); topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
topologyStore.getLinkExpressions(settings.value.linkClientExpressions || []); topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client);
topologyStore.getLinkExpressions(settings.value.linkServerExpressions || []); topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server);
} else { } else {
topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []); topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []);
topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []);
@ -239,10 +239,9 @@ limitations under the License. -->
setNodeTools(settings.value.nodeDashboard); setNodeTools(settings.value.nodeDashboard);
} }
function draw() { function computeLevels(calls: Call[], nodeList: Node[], levels: any[]) {
const node = findMostFrequent(topologyStore.calls); const node = findMostFrequent(calls);
const levels = []; const nodes = JSON.parse(JSON.stringify(nodeList)).sort((a: Node, b: Node) => {
const nodes = JSON.parse(JSON.stringify(topologyStore.nodes)).sort((a: Node, b: Node) => {
if (a.name.toLowerCase() < b.name.toLowerCase()) { if (a.name.toLowerCase() < b.name.toLowerCase()) {
return -1; return -1;
} }
@ -254,15 +253,14 @@ limitations under the License. -->
const index = nodes.findIndex((n: Node) => n.type === "USER"); const index = nodes.findIndex((n: Node) => n.type === "USER");
let key = index; let key = index;
if (index < 0) { if (index < 0) {
const idx = nodes.findIndex((n: Node) => n.id === node.id); key = nodes.findIndex((n: Node) => n.id === node.id);
key = idx;
} }
levels.push([nodes[key]]); levels.push([nodes[key]]);
nodes.splice(key, 1); nodes.splice(key, 1);
for (const level of levels) { for (const level of levels) {
const a = []; const a = [];
for (const l of level) { for (const l of level) {
for (const n of topologyStore.calls) { for (const n of calls) {
if (n.target === l.id) { if (n.target === l.id) {
const i = nodes.findIndex((d: Node) => d.id === n.source); const i = nodes.findIndex((d: Node) => d.id === n.source);
if (i > -1) { if (i > -1) {
@ -283,6 +281,18 @@ limitations under the License. -->
levels.push(a); levels.push(a);
} }
} }
if (nodes.length) {
const ids = nodes.map((d: Node) => d.id);
const links = calls.filter((item: Call) => ids.includes(item.source) || ids.includes(item.target));
const list = computeLevels(links, nodes, []);
levels = list.map((subArrayA, index) => subArrayA.concat(levels[index]));
}
return levels;
}
function draw() {
const levels = computeLevels(topologyStore.calls, topologyStore.nodes, []);
topologyLayout.value = layout(levels, topologyStore.calls, radius); topologyLayout.value = layout(levels, topologyStore.calls, radius);
graphWidth.value = topologyLayout.value.layout.width; graphWidth.value = topologyLayout.value.layout.width;
const drag: any = d3.drag().on("drag", (d: { x: number; y: number }) => { const drag: any = d3.drag().on("drag", (d: { x: number; y: number }) => {

View File

@ -69,7 +69,7 @@ limitations under the License. -->
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { EntityType, DepthList, MetricModes } from "../../../data"; import { EntityType, DepthList, MetricModes, CallTypes } from "../../../data";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import Sankey from "./Sankey.vue"; import Sankey from "./Sankey.vue";
import Settings from "./Settings.vue"; import Settings from "./Settings.vue";
@ -121,8 +121,8 @@ limitations under the License. -->
width.value = dom.width - 5; width.value = dom.width - 5;
if (settings.value.metricMode === MetricModes.Expression) { if (settings.value.metricMode === MetricModes.Expression) {
topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []); topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
topologyStore.getLinkExpressions(settings.value.linkClientExpressions || []); topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client);
topologyStore.getLinkExpressions(settings.value.linkServerExpressions || []); topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server);
} else { } else {
topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []);
topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []); topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []);

View File

@ -277,6 +277,7 @@ limitations under the License. -->
LegendOpt, LegendOpt,
MetricsType, MetricsType,
MetricModes, MetricModes,
CallTypes,
} from "../../../data"; } from "../../../data";
import type { Option } from "@/types/app"; import type { Option } from "@/types/app";
import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor"; import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
@ -515,7 +516,7 @@ limitations under the License. -->
topologyStore.setLinkServerMetrics({}); topologyStore.setLinkServerMetrics({});
return; return;
} }
topologyStore.getLinkExpressions(states.linkServerExpressions, "SERVER"); topologyStore.getLinkExpressions(states.linkServerExpressions, CallTypes.Server);
} }
function changeLinkClientExpressions(param: string[]) { function changeLinkClientExpressions(param: string[]) {
if (!isExpression.value) { if (!isExpression.value) {
@ -527,7 +528,7 @@ limitations under the License. -->
topologyStore.changeLinkClientMetrics({}); topologyStore.changeLinkClientMetrics({});
return; return;
} }
topologyStore.getLinkExpressions(states.linkClientExpressions, "CLIENT"); topologyStore.getLinkExpressions(states.linkClientExpressions, CallTypes.Client);
} }
function updateLinkClientMetrics(options: Option[] | any) { function updateLinkClientMetrics(options: Option[] | any) {
const opt = options.map((d: Option) => d.value); const opt = options.map((d: Option) => d.value);