fix: legend expressions

This commit is contained in:
Fine 2023-08-20 15:19:15 +08:00
parent 54fe200256
commit 26a055ef22
5 changed files with 53 additions and 22 deletions

View File

@ -315,7 +315,7 @@ export async function useExpressionsQueryPodsMetrics(
return expressionParams; return expressionParams;
} }
export function useQueryTopologyExpressionsProcessor(metrics: string[], source: any[], scope: string) { export function useQueryTopologyExpressionsProcessor(metrics: string[], instances: any[]) {
const appStore = useAppStoreWithOut(); const appStore = useAppStoreWithOut();
function getNodeExpressionQuery() { function getNodeExpressionQuery() {
@ -323,7 +323,7 @@ export function useQueryTopologyExpressionsProcessor(metrics: string[], source:
duration: appStore.durationTime, duration: appStore.durationTime,
}; };
const variables: string[] = [`$duration: Duration!`]; const variables: string[] = [`$duration: Duration!`];
const fragmentList = source.map((d: any, index: number) => { const fragmentList = instances.map((d: any, index: number) => {
const entity = { const entity = {
serviceName: d.sourceObj ? d.sourceObj.name : d.name, serviceName: d.sourceObj ? d.sourceObj.name : d.name,
normal: true, normal: true,
@ -348,7 +348,7 @@ export function useQueryTopologyExpressionsProcessor(metrics: string[], source:
} }
function handleExpressionValues(resp: { [key: string]: any }) { function handleExpressionValues(resp: { [key: string]: any }) {
const obj: any = {}; const obj: any = {};
for (let idx = 0; idx < source.length; idx++) { for (let idx = 0; idx < instances.length; idx++) {
for (let index = 0; index < metrics.length; index++) { for (let index = 0; index < metrics.length; index++) {
const k = "expression" + idx + index; const k = "expression" + idx + index;
if (metrics[index]) { if (metrics[index]) {
@ -357,7 +357,7 @@ export function useQueryTopologyExpressionsProcessor(metrics: string[], source:
values: [], values: [],
}; };
} }
obj[metrics[index]].values.push({ value: resp[k].results[0].values[0].value, id: source[idx].id }); obj[metrics[index]].values.push({ value: resp[k].results[0].values[0].value, id: instances[idx].id });
} }
} }
} }

View File

@ -26,7 +26,6 @@ import query from "@/graphql/fetch";
import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor"; import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor"; import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { MetricCatalog } from "@/views/dashboard/data";
interface MetricVal { interface MetricVal {
[key: string]: { values: { id: string; value: unknown }[] }; [key: string]: { values: { id: string; value: unknown }[] };
@ -116,6 +115,16 @@ export const topologyStore = defineStore({
setLinkClientMetrics(m: MetricVal) { setLinkClientMetrics(m: MetricVal) {
this.linkClientMetrics = m; this.linkClientMetrics = m;
}, },
setLegendValues(expressions: string, data: { [key: string]: any }) {
for (let idx = 0; idx < this.nodes.length; idx++) {
for (let index = 0; index < expressions.length; index++) {
const k = "expression" + idx + index;
if (expressions[index]) {
this.nodes[idx][expressions[index]] = Number(data[k].results[0].values[0].value);
}
}
}
},
async getDepthServiceTopology(serviceIds: string[], depth: number) { async getDepthServiceTopology(serviceIds: string[], depth: number) {
const res = await this.getServicesTopology(serviceIds); const res = await this.getServicesTopology(serviceIds);
if (depth > 1) { if (depth > 1) {
@ -376,7 +385,6 @@ export const topologyStore = defineStore({
const { getNodeExpressionQuery, handleExpressionValues } = useQueryTopologyExpressionsProcessor( const { getNodeExpressionQuery, handleExpressionValues } = useQueryTopologyExpressionsProcessor(
expressions, expressions,
calls, calls,
MetricCatalog.SERVICE_RELATION,
); );
const param = getNodeExpressionQuery(); const param = getNodeExpressionQuery();
const res = await this.getNodeExpressionValue(param); const res = await this.getNodeExpressionValue(param);
@ -419,7 +427,6 @@ export const topologyStore = defineStore({
const { getNodeExpressionQuery, handleExpressionValues } = useQueryTopologyExpressionsProcessor( const { getNodeExpressionQuery, handleExpressionValues } = useQueryTopologyExpressionsProcessor(
expressions, expressions,
this.nodes, this.nodes,
"",
); );
const param = getNodeExpressionQuery(); const param = getNodeExpressionQuery();
const res = await this.getNodeExpressionValue(param); const res = await this.getNodeExpressionValue(param);

View File

@ -37,7 +37,6 @@ declare module '@vue/runtime-core' {
ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTooltip: typeof import('element-plus/es')['ElTooltip']
Graph: typeof import('./../components/Graph.vue')['default'] Graph: typeof import('./../components/Graph.vue')['default']
Icon: typeof import('./../components/Icon.vue')['default'] Icon: typeof import('./../components/Icon.vue')['default']
'Icon copy': typeof import('./../components/Icon copy.vue')['default']
Loading: typeof import('element-plus/es')['ElLoadingDirective'] Loading: typeof import('element-plus/es')['ElLoadingDirective']
Radio: typeof import('./../components/Radio.vue')['default'] Radio: typeof import('./../components/Radio.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']

View File

@ -153,6 +153,7 @@ limitations under the License. -->
import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor"; import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
import { layout, circleIntersection, computeCallPos } from "./utils/layout"; import { layout, circleIntersection, computeCallPos } from "./utils/layout";
import zoom from "../../components/utils/zoom"; import zoom from "../../components/utils/zoom";
import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor";
/*global Nullable, defineProps */ /*global Nullable, defineProps */
const props = defineProps({ const props = defineProps({
@ -184,7 +185,6 @@ limitations under the License. -->
const currentNode = ref<Nullable<Node>>(); const currentNode = ref<Nullable<Node>>();
const diff = computed(() => [(width.value - graphWidth.value - 130) / 2, 100]); const diff = computed(() => [(width.value - graphWidth.value - 130) / 2, 100]);
const radius = 8; const radius = 8;
const isExpression = computed(() => settings.value.metricMode === MetricModes.Expression);
onMounted(async () => { onMounted(async () => {
await nextTick(); await nextTick();
@ -221,10 +221,10 @@ limitations under the License. -->
} }
async function update() { async function update() {
if (isExpression.value) { if (settings.value.metricMode === MetricModes.Expression) {
topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []); topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); topologyStore.getLinkExpressions(settings.value.linkClientExpressions || []);
topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []); topologyStore.getLinkExpressions(settings.value.linkServerExpressions || []);
} else { } else {
topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []); topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []);
topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []);
@ -237,6 +237,7 @@ limitations under the License. -->
tooltip.value = d3.select("#tooltip"); tooltip.value = d3.select("#tooltip");
setNodeTools(settings.value.nodeDashboard); setNodeTools(settings.value.nodeDashboard);
} }
function draw() { function draw() {
const node = findMostFrequent(topologyStore.calls); const node = findMostFrequent(topologyStore.calls);
const levels = []; const levels = [];
@ -360,8 +361,18 @@ limitations under the License. -->
} }
async function initLegendMetrics() { async function initLegendMetrics() {
const ids = topologyStore.nodes.map((d: Node) => d.id);
const names = props.config.legend.map((d: any) => d.name); const names = props.config.legend.map((d: any) => d.name);
if (settings.value.metricMode === MetricModes.Expression) {
const { getNodeExpressionQuery } = useQueryTopologyExpressionsProcessor(names, topologyStore.nodes);
const param = getNodeExpressionQuery();
const res = await topologyStore.getNodeExpressionValue(param);
if (res.errors) {
ElMessage.error(res.errors);
} else {
topologyStore.setLegendValues(names, res.data);
}
} else {
const ids = topologyStore.nodes.map((d: Node) => d.id);
if (names.length && ids.length) { if (names.length && ids.length) {
const param = await useQueryTopologyMetrics(names, ids); const param = await useQueryTopologyMetrics(names, ids);
const res = await topologyStore.getLegendMetrics(param); const res = await topologyStore.getLegendMetrics(param);
@ -370,6 +381,8 @@ limitations under the License. -->
} }
} }
} }
}
function getNodeStatus(d: any) { function getNodeStatus(d: any) {
const legend = settings.value.legend; const legend = settings.value.legend;
if (!legend) { if (!legend) {

View File

@ -202,7 +202,6 @@ limitations under the License. -->
v-if="isExpression" v-if="isExpression"
v-model="metric.name" v-model="metric.name"
placeholder="Please input a expression" placeholder="Please input a expression"
type="number"
@change="changeLegend(LegendOpt.NAME, $event, index)" @change="changeLegend(LegendOpt.NAME, $event, index)"
size="small" size="small"
class="item" class="item"
@ -270,6 +269,7 @@ limitations under the License. -->
} 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";
import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor";
import type { Node } from "@/types/topology"; import type { Node } from "@/types/topology";
import type { DashboardItem, MetricConfigOpt } from "@/types/dashboard"; import type { DashboardItem, MetricConfigOpt } from "@/types/dashboard";
import Metrics from "./Metrics.vue"; import Metrics from "./Metrics.vue";
@ -372,18 +372,30 @@ limitations under the License. -->
} }
async function setLegend() { async function setLegend() {
updateSettings(); updateSettings();
const ids = topologyStore.nodes.map((d: Node) => d.id);
const names = dashboardStore.selectedGrid.legend.map((d: any) => d.name); const names = dashboardStore.selectedGrid.legend.map((d: any) => d.name);
if (!names.length) { if (!names.length) {
emit("updateNodes"); emit("updateNodes");
return; return;
} }
if (isExpression.value) {
const { getNodeExpressionQuery } = useQueryTopologyExpressionsProcessor(names, topologyStore.nodes);
const param = getNodeExpressionQuery();
const res = await topologyStore.getNodeExpressionValue(param);
if (res.errors) {
ElMessage.error(res.errors);
} else {
topologyStore.setLegendValues(names, res.data);
}
} else {
const ids = topologyStore.nodes.map((d: Node) => d.id);
const param = await useQueryTopologyMetrics(names, ids); const param = await useQueryTopologyMetrics(names, ids);
const res = await topologyStore.getLegendMetrics(param); const res = await topologyStore.getLegendMetrics(param);
if (res.errors) { if (res.errors) {
ElMessage.error(res.errors); ElMessage.error(res.errors);
} }
}
emit("updateNodes"); emit("updateNodes");
} }
function changeNodeDashboard(opt: any) { function changeNodeDashboard(opt: any) {