diff --git a/src/hooks/useExpressionsProcessor.ts b/src/hooks/useExpressionsProcessor.ts index 6855696f..97321be0 100644 --- a/src/hooks/useExpressionsProcessor.ts +++ b/src/hooks/useExpressionsProcessor.ts @@ -22,6 +22,7 @@ import { useSelectorStore } from "@/store/modules/selectors"; import { useAppStoreWithOut } from "@/store/modules/app"; import type { MetricConfigOpt } from "@/types/dashboard"; import type { Instance, Endpoint, Service } from "@/types/selector"; +import type { Node, Call } from "@/types/topology"; export async function useExpressionsQueryProcessor(config: Indexable) { function expressionsGraphqlPods() { @@ -312,3 +313,34 @@ export async function useExpressionsQueryPodsMetrics( return expressionParams; } + +export function useQueryTopologyExpressionsProcessor(metrics: string[]) { + const appStore = useAppStoreWithOut(); + + function getNodeExpressions(nodes: Node[]) { + const conditions: { [key: string]: unknown } = { + duration: appStore.durationTime, + }; + const variables: string[] = [`$duration: Duration!`]; + const fragmentList = nodes.map((d: Node, index: number) => { + const entity = { + serviceName: d.name, + normal: true, + }; + variables.push(`$entity${index}: Entity!`); + conditions[`entity${index}`] = entity; + const f = metrics.map((name: string, idx: number) => { + variables.push(`$expression${index}${idx}: String!`); + conditions[`expression${index}${idx}`] = name; + return `expression${index}${idx}: execExpression(expression: $expression${index}${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`; + }); + return f; + }); + const fragment = fragmentList.flat(1).join(" "); + const queryStr = `query queryData(${variables}) {${fragment}}`; + + return { queryStr, conditions }; + } + + return { getNodeExpressions }; +} diff --git a/src/store/modules/topology.ts b/src/store/modules/topology.ts index 50bae018..6ce9fad0 100644 --- a/src/store/modules/topology.ts +++ b/src/store/modules/topology.ts @@ -24,6 +24,7 @@ import { useAppStoreWithOut } from "@/store/modules/app"; import type { AxiosResponse } from "axios"; import query from "@/graphql/fetch"; import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor"; +import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor"; import { ElMessage } from "element-plus"; interface MetricVal { @@ -318,9 +319,20 @@ export const topologyStore = defineStore({ if (res.data.errors) { return res.data; } + console.log(res.data.data); this.setNodeMetricValue(res.data.data); return res.data; }, + async getNodeExpressionValue(param: { queryStr: string; conditions: { [key: string]: unknown } }) { + const res: AxiosResponse = await query(param); + + if (res.data.errors) { + return res.data; + } + console.log(res.data.data); + // this.setNodeMetricValue(res.data.data); + return res.data; + }, async getLinkClientMetrics(linkClientMetrics: string[]) { if (!linkClientMetrics.length) { this.setLinkClientMetrics({}); @@ -358,6 +370,7 @@ export const topologyStore = defineStore({ this.setNodeMetricValue({}); return; } + console.log(this.nodes); const ids = this.nodes.map((d: Node) => d.id); if (!ids.length) { return; @@ -369,6 +382,22 @@ export const topologyStore = defineStore({ ElMessage.error(res.errors); } }, + async queryNodeExpressions(expressions: string[]) { + if (!expressions.length) { + this.setNodeMetricValue({}); + return; + } + if (!this.nodes.length) { + return; + } + const { getNodeExpressions } = useQueryTopologyExpressionsProcessor(expressions); + const param = getNodeExpressions(this.nodes); + const res = await this.getNodeExpressionValue(param); + + if (res.errors) { + ElMessage.error(res.errors); + } + }, async getLegendMetrics(param: { queryStr: string; conditions: { [key: string]: unknown } }) { const res: AxiosResponse = await query(param); diff --git a/src/views/dashboard/related/topology/components/Graph.vue b/src/views/dashboard/related/topology/components/Graph.vue index f6318aeb..427c004e 100644 --- a/src/views/dashboard/related/topology/components/Graph.vue +++ b/src/views/dashboard/related/topology/components/Graph.vue @@ -139,7 +139,7 @@ limitations under the License. --> import { useSelectorStore } from "@/store/modules/selectors"; import { useTopologyStore } from "@/store/modules/topology"; import { useDashboardStore } from "@/store/modules/dashboard"; - import { EntityType, DepthList } from "../../../data"; + import { EntityType, DepthList, MetricModes } from "../../../data"; import router from "@/router"; import { ElMessage } from "element-plus"; import Settings from "./Settings.vue"; @@ -184,6 +184,7 @@ limitations under the License. --> const currentNode = ref>(); const diff = computed(() => [(width.value - graphWidth.value - 130) / 2, 100]); const radius = 8; + const isExpression = ref(settings.value.metricMode === MetricModes.Expression ? true : false); onMounted(async () => { await nextTick(); @@ -220,9 +221,16 @@ limitations under the License. --> } async function update() { - topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []); - topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); - topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []); + if (isExpression.value) { + topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []); + topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); + topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []); + } else { + topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []); + topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); + topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []); + } + window.addEventListener("resize", resize); await initLegendMetrics(); draw(); diff --git a/src/views/dashboard/related/topology/components/Settings.vue b/src/views/dashboard/related/topology/components/Settings.vue index 8d66e541..d636240c 100644 --- a/src/views/dashboard/related/topology/components/Settings.vue +++ b/src/views/dashboard/related/topology/components/Settings.vue @@ -395,6 +395,9 @@ limitations under the License. --> linkServerMetrics: states.linkServerMetrics, linkClientMetrics: states.linkClientMetrics, nodeMetrics: states.nodeMetrics, + linkServerExpressions: states.linkServerExpressions, + linkClientExpressions: states.linkClientExpressions, + nodeExpressions: states.nodeExpressions, legend: metrics, ...metricConfig, description,