This is an automated email from the ASF dual-hosted git repository.

wankai pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-booster-ui.git


The following commit(s) were added to refs/heads/main by this push:
     new 03f321b6 refactor: remove the `General ` metric mode and related 
logical code (#384)
03f321b6 is described below

commit 03f321b62ae0b3581f156954f75429a52ef511b6
Author: Fine0830 <fanxue0...@gmail.com>
AuthorDate: Thu Apr 11 17:50:43 2024 +0800

    refactor: remove the `General ` metric mode and related logical code (#384)
---
 src/hooks/data.ts                                  |  69 ----
 src/hooks/useExpressionsProcessor.ts               |   6 +-
 src/hooks/useListConfig.ts                         |  41 --
 src/hooks/useMetricsProcessor.ts                   | 437 ---------------------
 src/locales/lang/en.ts                             |   1 -
 src/locales/lang/es.ts                             |   1 -
 src/locales/lang/zh.ts                             |   1 -
 src/store/modules/dashboard.ts                     |  14 +-
 src/store/modules/topology.ts                      |  99 -----
 src/types/dashboard.d.ts                           |   4 -
 src/views/dashboard/List.vue                       |  25 +-
 src/views/dashboard/Widget.vue                     |  44 +--
 src/views/dashboard/components/WidgetLink.vue      |  18 +-
 src/views/dashboard/configuration/Widget.vue       |  21 -
 .../configuration/widget/metric/Index.vue          | 314 +++------------
 .../configuration/widget/metric/Standard.vue       |  49 +--
 src/views/dashboard/controls/Widget.vue            |  42 +-
 src/views/dashboard/data.ts                        |  86 ----
 src/views/dashboard/graphs/EndpointList.vue        |  51 +--
 src/views/dashboard/graphs/InstanceList.vue        |  53 +--
 src/views/dashboard/graphs/ServiceList.vue         |  58 +--
 src/views/dashboard/graphs/Table.vue               |   5 -
 src/views/dashboard/graphs/TopList.vue             |  14 +-
 .../dashboard/graphs/components/ColumnGraph.vue    |  36 +-
 .../dashboard/related/topology/config/Metrics.vue  |  33 +-
 .../dashboard/related/topology/config/Settings.vue | 311 ++-------------
 .../dashboard/related/topology/pod/InstanceMap.vue |   5 +-
 .../dashboard/related/topology/pod/PodMap.vue      |  14 +-
 .../dashboard/related/topology/pod/Sankey.vue      |  31 +-
 .../related/topology/service/HierarchyMap.vue      |   4 +-
 .../related/topology/service/ServiceMap.vue        | 107 ++---
 31 files changed, 204 insertions(+), 1790 deletions(-)

diff --git a/src/hooks/data.ts b/src/hooks/data.ts
index 3d45a00d..f7c2b2db 100644
--- a/src/hooks/data.ts
+++ b/src/hooks/data.ts
@@ -14,32 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-export enum MetricQueryTypes {
-  ReadMetricsValue = "readMetricsValue",
-  ReadMetricsValues = "readMetricsValues",
-  SortMetrics = "sortMetrics",
-  ReadLabeledMetricsValues = "readLabeledMetricsValues",
-  READHEATMAP = "readHeatMap",
-  ReadSampledRecords = "readSampledRecords",
-  ReadRecords = "readRecords",
-  ReadNullableMetricsValue = "readNullableMetricsValue",
-}
 
-export enum Calculations {
-  Percentage = "percentage",
-  ByteToKB = "byteToKB",
-  ByteToMB = "byteToMB",
-  ByteToGB = "byteToGB",
-  Apdex = "apdex",
-  ConvertSeconds = "convertSeconds",
-  ConvertMilliseconds = "convertMilliseconds",
-  MsToS = "msTos",
-  Average = "average",
-  PercentageAvg = "percentageAvg",
-  ApdexAvg = "apdexAvg",
-  SecondToDay = "secondToDay",
-  NanosecondToMillisecond = "nanosecondToMillisecond",
-}
 export enum sizeEnum {
   XS = "XS",
   SM = "SM",
@@ -68,50 +43,6 @@ screenMap.set(sizeEnum.XL, screenEnum.XL);
 screenMap.set(sizeEnum.XXL, screenEnum.XXL);
 
 export const RespFields: Indexable = {
-  readMetricsValues: `{
-    label
-    values {
-      values {value isEmptyValue}
-    }
-  }`,
-  readMetricsValue: ``,
-  readNullableMetricsValue: `{
-    value
-    isEmptyValue
-  }`,
-  sortMetrics: `{
-    name
-    id
-    value
-    refId
-  }`,
-  readLabeledMetricsValues: `{
-    label
-    values {
-      values {value isEmptyValue}
-    }
-  }`,
-  readHeatMap: `{
-    values {
-      id
-      values
-    }
-    buckets {
-      min
-      max
-    }
-  }`,
-  readSampledRecords: `{
-    name
-    value
-    refId
-  }`,
-  readRecords: `{
-    id
-    name
-    value
-    refId
-  }`,
   execExpression: `{
     type
     results {
diff --git a/src/hooks/useExpressionsProcessor.ts 
b/src/hooks/useExpressionsProcessor.ts
index 60c66abe..080469ae 100644
--- a/src/hooks/useExpressionsProcessor.ts
+++ b/src/hooks/useExpressionsProcessor.ts
@@ -129,9 +129,9 @@ export async function useExpressionsQueryProcessor(config: 
Indexable) {
         }
         if (type === ExpressionResultType.SINGLE_VALUE) {
           for (const item of results) {
-            const label = item.metric.labels
-              .map((d: { key: string; value: string }) => 
`${d.key}=${d.value}`)
-              .join(",");
+            const label =
+              item.metric &&
+              item.metric.labels.map((d: { key: string; value: string }) => 
`${d.key}=${d.value}`).join(",");
             const values = item.values.map((d: { value: unknown }) => d.value) 
|| [];
             if (results.length === 1) {
               source[label || c.label || name] = values;
diff --git a/src/hooks/useListConfig.ts b/src/hooks/useListConfig.ts
deleted file mode 100644
index d0705b5d..00000000
--- a/src/hooks/useListConfig.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { MetricQueryTypes, Calculations } from "./data";
-import { MetricModes } from "@/views/dashboard/data";
-
-export function useListConfig(config: Indexable, index: number) {
-  if (config.metricModes === MetricModes.Expression) {
-    return {
-      isLinear: false,
-      isAvg: true,
-    };
-  }
-  const i = Number(index);
-  const types = [Calculations.Average, Calculations.ApdexAvg, 
Calculations.PercentageAvg];
-  const calculation = config.metricConfig && config.metricConfig[i] && 
config.metricConfig[i].calculation;
-  const isLinear =
-    [MetricQueryTypes.ReadMetricsValues, 
MetricQueryTypes.ReadLabeledMetricsValues].includes(config.metricTypes[i]) &&
-    !types.includes(calculation);
-  const isAvg =
-    [MetricQueryTypes.ReadMetricsValues, 
MetricQueryTypes.ReadLabeledMetricsValues].includes(config.metricTypes[i]) &&
-    types.includes(calculation);
-
-  return {
-    isLinear,
-    isAvg,
-  };
-}
diff --git a/src/hooks/useMetricsProcessor.ts b/src/hooks/useMetricsProcessor.ts
deleted file mode 100644
index b8ecc895..00000000
--- a/src/hooks/useMetricsProcessor.ts
+++ /dev/null
@@ -1,437 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import dayjs from "dayjs";
-import { RespFields, MetricQueryTypes, Calculations } from "./data";
-import { ElMessage } from "element-plus";
-import { useDashboardStore } from "@/store/modules/dashboard";
-import { useSelectorStore } from "@/store/modules/selectors";
-import { useAppStoreWithOut } from "@/store/modules/app";
-import type { Instance, Endpoint, Service } from "@/types/selector";
-import type { MetricConfigOpt } from "@/types/dashboard";
-
-export function useQueryProcessor(config: Indexable) {
-  if (!(config.metrics && config.metrics[0])) {
-    return;
-  }
-  if (!(config.metricTypes && config.metricTypes[0])) {
-    return;
-  }
-  const appStore = useAppStoreWithOut();
-  const dashboardStore = useDashboardStore();
-  const selectorStore = useSelectorStore();
-
-  if (!selectorStore.currentService && dashboardStore.entity !== "All") {
-    return;
-  }
-  const conditions: Recordable = {
-    duration: appStore.durationTime,
-  };
-  const variables: string[] = [`$duration: Duration!`];
-  const isRelation = ["ServiceRelation", "ServiceInstanceRelation", 
"EndpointRelation", "ProcessRelation"].includes(
-    dashboardStore.entity,
-  );
-  if (isRelation && !selectorStore.currentDestService) {
-    return;
-  }
-  const fragment = config.metrics.map((name: string, index: number) => {
-    const metricType = config.metricTypes[index] || "";
-    const c = (config.metricConfig && config.metricConfig[index]) || {};
-    if ([MetricQueryTypes.ReadSampledRecords, 
MetricQueryTypes.SortMetrics].includes(metricType)) {
-      variables.push(`$condition${index}: TopNCondition!`);
-      conditions[`condition${index}`] = {
-        name,
-        parentService: ["All"].includes(dashboardStore.entity) ? null : 
selectorStore.currentService.value,
-        normal: selectorStore.currentService ? 
selectorStore.currentService.normal : true,
-        topN: Number(c.topN) || 10,
-        order: c.sortOrder || "DES",
-      };
-    } else {
-      const entity = {
-        serviceName: dashboardStore.entity === "All" ? undefined : 
selectorStore.currentService.value,
-        normal: dashboardStore.entity === "All" ? undefined : 
selectorStore.currentService.normal,
-        serviceInstanceName: ["ServiceInstance", "ServiceInstanceRelation", 
"ProcessRelation"].includes(
-          dashboardStore.entity,
-        )
-          ? selectorStore.currentPod && selectorStore.currentPod.value
-          : undefined,
-        endpointName: dashboardStore.entity.includes("Endpoint")
-          ? selectorStore.currentPod && selectorStore.currentPod.value
-          : undefined,
-        processName: dashboardStore.entity.includes("Process")
-          ? selectorStore.currentProcess && selectorStore.currentProcess.value
-          : undefined,
-        destNormal: isRelation ? selectorStore.currentDestService.normal : 
undefined,
-        destServiceName: isRelation ? selectorStore.currentDestService.value : 
undefined,
-        destServiceInstanceName: ["ServiceInstanceRelation", 
"ProcessRelation"].includes(dashboardStore.entity)
-          ? selectorStore.currentDestPod && selectorStore.currentDestPod.value
-          : undefined,
-        destEndpointName:
-          dashboardStore.entity === "EndpointRelation"
-            ? selectorStore.currentDestPod && 
selectorStore.currentDestPod.value
-            : undefined,
-        destProcessName: dashboardStore.entity.includes("ProcessRelation")
-          ? selectorStore.currentDestProcess && 
selectorStore.currentDestProcess.value
-          : undefined,
-      };
-      if ([MetricQueryTypes.ReadRecords].includes(metricType)) {
-        variables.push(`$condition${index}: RecordCondition!`);
-        conditions[`condition${index}`] = {
-          name,
-          parentEntity: entity,
-          topN: Number(c.topN) || 10,
-          order: c.sortOrder || "DES",
-        };
-      } else {
-        if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
-          const labels = (c.labelsIndex || "").split(",").map((item: string) 
=> item.replace(/^\s*|\s*$/g, ""));
-          variables.push(`$labels${index}: [String!]!`);
-          conditions[`labels${index}`] = labels;
-        }
-        variables.push(`$condition${index}: MetricsCondition!`);
-        conditions[`condition${index}`] = {
-          name,
-          entity,
-        };
-      }
-    }
-    if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
-      return `${name}${index}: ${metricType}(condition: $condition${index}, 
labels: $labels${index}, duration: $duration)${RespFields[metricType]}`;
-    }
-    const t = metricType === MetricQueryTypes.ReadMetricsValue ? 
MetricQueryTypes.ReadNullableMetricsValue : metricType;
-
-    return `${name}${index}: ${t}(condition: $condition${index}, duration: 
$duration)${RespFields[t]}`;
-  });
-  const queryStr = `query queryData(${variables}) {${fragment}}`;
-
-  return {
-    queryStr,
-    conditions,
-  };
-}
-export function useSourceProcessor(
-  resp: { errors: string; data: Indexable },
-  config: {
-    metrics: string[];
-    metricTypes: string[];
-    metricConfig: MetricConfigOpt[];
-  },
-) {
-  if (resp.errors) {
-    ElMessage.error(resp.errors);
-    return {};
-  }
-  if (!resp.data) {
-    ElMessage.error("The query is wrong");
-    return {};
-  }
-  const source: { [key: string]: unknown } = {};
-  const keys = Object.keys(resp.data);
-
-  config.metricTypes.forEach((type: string, index) => {
-    const m = config.metrics[index];
-    const c = (config.metricConfig && config.metricConfig[index]) || {};
-
-    if (type === MetricQueryTypes.ReadMetricsValues) {
-      source[c.label || m] = (resp.data[keys[index]] && 
calculateExp(resp.data[keys[index]].values.values, c)) || [];
-    }
-    if (type === MetricQueryTypes.ReadLabeledMetricsValues) {
-      const resVal = Object.values(resp.data)[0] || [];
-      const labels = (c.label || "").split(",").map((item: string) => 
item.replace(/^\s*|\s*$/g, ""));
-      const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => 
item.replace(/^\s*|\s*$/g, ""));
-      for (const item of resVal) {
-        const values = item.values.values.map((d: { value: number; 
isEmptyValue: boolean }) =>
-          d.isEmptyValue ? NaN : aggregation(Number(d.value), c),
-        );
-        const indexNum = labelsIdx.findIndex((d: string) => d === item.label);
-        if (labels[indexNum] && indexNum > -1) {
-          source[labels[indexNum]] = values;
-        } else {
-          source[item.label] = values;
-        }
-      }
-    }
-    if (type === MetricQueryTypes.ReadMetricsValue) {
-      const v = Object.values(resp.data)[0] || {};
-      source[m] = v.isEmptyValue ? NaN : aggregation(Number(v.value), c);
-    }
-    if (
-      (
-        [MetricQueryTypes.ReadRecords, MetricQueryTypes.ReadSampledRecords, 
MetricQueryTypes.SortMetrics] as string[]
-      ).includes(type)
-    ) {
-      source[m] = (Object.values(resp.data)[0] || []).map((d: { value: 
unknown; name: string }) => {
-        d.value = aggregation(Number(d.value), c);
-
-        return d;
-      });
-    }
-    if (type === MetricQueryTypes.READHEATMAP) {
-      const resVal = Object.values(resp.data)[0] || {};
-      const nodes = [] as Indexable[];
-      if (!(resVal && resVal.values)) {
-        source[m] = { nodes: [] };
-        return;
-      }
-      resVal.values.forEach((items: { values: number[] }, x: number) => {
-        const grids = items.values.map((val: number, y: number) => [x, y, 
val]);
-
-        nodes.push(...grids);
-      });
-      let buckets = [] as Indexable[];
-      if (resVal.buckets.length) {
-        buckets = [resVal.buckets[0].min, ...resVal.buckets.map((item: { min: 
string; max: string }) => item.max)];
-      }
-
-      source[m] = { nodes, buckets }; // nodes: number[][]
-    }
-  });
-
-  return source;
-}
-
-export function useQueryPodsMetrics(
-  pods: Array<(Instance | Endpoint | Service) & Indexable>,
-  config: {
-    metrics: string[];
-    metricTypes: string[];
-    metricConfig: MetricConfigOpt[];
-  },
-  scope: string,
-) {
-  const metricTypes = (config.metricTypes || []).filter((m: string) => m);
-  if (!metricTypes.length) {
-    return;
-  }
-  const metrics = (config.metrics || []).filter((m: string) => m);
-  if (!metrics.length) {
-    return;
-  }
-  const appStore = useAppStoreWithOut();
-  const selectorStore = useSelectorStore();
-  const conditions: { [key: string]: unknown } = {
-    duration: appStore.durationTime,
-  };
-  const variables: string[] = [`$duration: Duration!`];
-  const currentService = selectorStore.currentService || {};
-  const fragmentList = pods.map((d: (Instance | Endpoint | Service) & 
Indexable, index: number) => {
-    const param = {
-      serviceName: scope === "Service" ? d.label : currentService.label,
-      serviceInstanceName: scope === "ServiceInstance" ? d.label : undefined,
-      endpointName: scope === "Endpoint" ? d.label : undefined,
-      normal: scope === "Service" ? d.normal : currentService.normal,
-    };
-    const f = metrics.map((name: string, idx: number) => {
-      const metricType = metricTypes[idx] || "";
-      variables.push(`$condition${index}${idx}: MetricsCondition!`);
-      conditions[`condition${index}${idx}`] = {
-        name,
-        entity: param,
-      };
-      let labelStr = "";
-      if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
-        const c = config.metricConfig[idx] || {};
-        variables.push(`$labels${index}${idx}: [String!]!`);
-        labelStr = `labels: $labels${index}${idx}, `;
-        const labels = (c.labelsIndex || "").split(",").map((item: string) => 
item.replace(/^\s*|\s*$/g, ""));
-        conditions[`labels${index}${idx}`] = labels;
-      }
-      const t =
-        metricType === MetricQueryTypes.ReadMetricsValue ? 
MetricQueryTypes.ReadNullableMetricsValue : metricType;
-      return `${name}${index}${idx}: ${t}(condition: $condition${index}${idx}, 
${labelStr}duration: $duration)${RespFields[t]}`;
-    });
-    return f;
-  });
-  const fragment = fragmentList.flat(1).join(" ");
-  const queryStr = `query queryData(${variables}) {${fragment}}`;
-
-  return { queryStr, conditions };
-}
-
-export function usePodsSource(
-  pods: Array<Instance | Endpoint>,
-  resp: { errors: string; data: Indexable },
-  config: {
-    metrics: string[];
-    metricTypes: string[];
-    metricConfig: MetricConfigOpt[];
-  },
-): Indexable {
-  if (resp.errors) {
-    ElMessage.error(resp.errors);
-    return {};
-  }
-  const names: string[] = [];
-  const metricConfigArr: MetricConfigOpt[] = [];
-  const metricTypesArr: string[] = [];
-  const data = pods.map((d: any, idx: number) => {
-    config.metrics.map((name: string, index: number) => {
-      const c: any = (config.metricConfig && config.metricConfig[index]) || {};
-      const key = name + idx + index;
-      if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValue) {
-        const v = resp.data[key];
-        d[name] = v.isEmptyValue ? NaN : aggregation(v.value, c);
-        if (idx === 0) {
-          names.push(name);
-          metricConfigArr.push(c);
-          metricTypesArr.push(config.metricTypes[index]);
-        }
-      }
-      if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValues) {
-        d[name] = {};
-        if ([Calculations.Average, Calculations.ApdexAvg, 
Calculations.PercentageAvg].includes(c.calculation)) {
-          d[name]["avg"] = calculateExp(resp.data[key].values.values, c);
-        }
-        d[name]["values"] = resp.data[key].values.values.map((val: { value: 
number; isEmptyValue: boolean }) =>
-          val.isEmptyValue ? NaN : aggregation(val.value, c),
-        );
-        if (idx === 0) {
-          names.push(name);
-          metricConfigArr.push(c);
-          metricTypesArr.push(config.metricTypes[index]);
-        }
-      }
-      if (config.metricTypes[index] === 
MetricQueryTypes.ReadLabeledMetricsValues) {
-        const resVal = resp.data[key] || [];
-        const labels = (c.label || "").split(",").map((item: string) => 
item.replace(/^\s*|\s*$/g, ""));
-        const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) 
=> item.replace(/^\s*|\s*$/g, ""));
-        for (let i = 0; i < resVal.length; i++) {
-          const item = resVal[i];
-          const values = item.values.values.map((d: { value: number; 
isEmptyValue: boolean }) =>
-            d.isEmptyValue ? NaN : aggregation(Number(d.value), c),
-          );
-          const indexNum = labelsIdx.findIndex((d: string) => d === 
item.label);
-          let key = item.label;
-          if (labels[indexNum] && indexNum > -1) {
-            key = labels[indexNum];
-          }
-          if (!d[key]) {
-            d[key] = {};
-          }
-          if ([Calculations.Average, Calculations.ApdexAvg, 
Calculations.PercentageAvg].includes(c.calculation)) {
-            d[key]["avg"] = calculateExp(item.values.values, c);
-          }
-          d[key]["values"] = values;
-          if (idx === 0) {
-            names.push(key);
-            metricConfigArr.push({ ...c, index: i });
-            metricTypesArr.push(config.metricTypes[index]);
-          }
-        }
-      }
-    });
-    return d;
-  });
-  return { data, names, metricConfigArr, metricTypesArr };
-}
-export function useQueryTopologyMetrics(metrics: string[], ids: string[]) {
-  const appStore = useAppStoreWithOut();
-  const conditions: { [key: string]: unknown } = {
-    duration: appStore.durationTime,
-    ids,
-  };
-  const variables: string[] = [`$duration: Duration!`, `$ids: [ID!]!`];
-  const fragmentList = metrics.map((d: string, index: number) => {
-    conditions[`m${index}`] = d;
-    variables.push(`$m${index}: String!`);
-
-    return `${d}: getValues(metric: {
-      name: $m${index}
-      ids: $ids
-    }, duration: $duration) {
-      values {
-        id
-        value
-      }
-    }`;
-  });
-  const queryStr = `query queryData(${variables}) {${fragmentList.join(" ")}}`;
-
-  return { queryStr, conditions };
-}
-export function calculateExp(
-  list: { value: number; isEmptyValue: boolean }[],
-  config: { calculation?: string },
-): (number | string)[] {
-  const arr = list.filter((d: { value: number; isEmptyValue: boolean }) => 
!d.isEmptyValue);
-  const sum = arr.length ? arr.map((d: { value: number }) => 
Number(d.value)).reduce((a, b) => a + b) : 0;
-  let data: (number | string)[] = [];
-  switch (config.calculation) {
-    case Calculations.Average:
-      data = [(sum / arr.length).toFixed(2)];
-      break;
-    case Calculations.PercentageAvg:
-      data = [(sum / arr.length / 100).toFixed(2)];
-      break;
-    case Calculations.ApdexAvg:
-      data = [(sum / arr.length / 10000).toFixed(2)];
-      break;
-    default:
-      data = list.map((d: { value: number; isEmptyValue: boolean }) =>
-        d.isEmptyValue ? NaN : aggregation(d.value, config),
-      );
-      break;
-  }
-  return data;
-}
-
-export function aggregation(val: number, config: { calculation?: string }): 
number | string {
-  let data: number | string = Number(val);
-
-  switch (config.calculation) {
-    case Calculations.Percentage:
-      data = (val / 100).toFixed(2);
-      break;
-    case Calculations.PercentageAvg:
-      data = (val / 100).toFixed(2);
-      break;
-    case Calculations.ByteToKB:
-      data = (val / 1024).toFixed(2);
-      break;
-    case Calculations.ByteToMB:
-      data = (val / 1024 / 1024).toFixed(2);
-      break;
-    case Calculations.ByteToGB:
-      data = (val / 1024 / 1024 / 1024).toFixed(2);
-      break;
-    case Calculations.Apdex:
-      data = (val / 10000).toFixed(2);
-      break;
-    case Calculations.ConvertSeconds:
-      data = dayjs(val * 1000).format("YYYY-MM-DD HH:mm:ss");
-      break;
-    case Calculations.ConvertMilliseconds:
-      data = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
-      break;
-    case Calculations.MsToS:
-      data = (val / 1000).toFixed(2);
-      break;
-    case Calculations.SecondToDay:
-      data = (val / 86400).toFixed(2);
-      break;
-    case Calculations.NanosecondToMillisecond:
-      data = (val / 1000 / 1000).toFixed(2);
-      break;
-    case Calculations.ApdexAvg:
-      data = (val / 10000).toFixed(2);
-      break;
-    default:
-      data;
-      break;
-  }
-
-  return data;
-}
diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts
index 9c9e065f..3fd57937 100644
--- a/src/locales/lang/en.ts
+++ b/src/locales/lang/en.ts
@@ -377,7 +377,6 @@ const msg = {
   menus: "Menus",
   saveReload: "Save and reload the page",
   document: "Documentation",
-  metricMode: "Metric Mode",
   addExpressions: "Add Expressions",
   expressions: "Expression",
   unhealthyExpression: "Unhealthy Expression",
diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts
index dd08fad3..f9e1ef7f 100644
--- a/src/locales/lang/es.ts
+++ b/src/locales/lang/es.ts
@@ -377,7 +377,6 @@ const msg = {
   menus: "Menus",
   saveReload: "Save and reload the page",
   document: "Documentation",
-  metricMode: "Metric Mode",
   addExpressions: "Add Expressions",
   expressions: "Expression",
   unhealthyExpression: "Unhealthy Expression",
diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts
index 7549cc07..18a8dbfe 100644
--- a/src/locales/lang/zh.ts
+++ b/src/locales/lang/zh.ts
@@ -375,7 +375,6 @@ const msg = {
   menusManagement: "菜单",
   saveReload: "保存并重新加载页面",
   document: "文档",
-  metricMode: "指标模式",
   addExpressions: "添加表达式",
   expressions: "表达式",
   unhealthyExpression: "非健康表达式",
diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts
index 46f6cac3..666577c6 100644
--- a/src/store/modules/dashboard.ts
+++ b/src/store/modules/dashboard.ts
@@ -24,7 +24,7 @@ import { useSelectorStore } from "@/store/modules/selectors";
 import { NewControl, TextConfig, TimeRangeConfig, ControlsTypes } from 
"../data";
 import type { AxiosResponse } from "axios";
 import { ElMessage } from "element-plus";
-import { EntityType, MetricModes, WidgetType } from "@/views/dashboard/data";
+import { EntityType, WidgetType } from "@/views/dashboard/data";
 interface DashboardState {
   showConfig: boolean;
   layout: LayoutConfig[];
@@ -88,13 +88,7 @@ export const dashboardStore = defineStore({
         i: index,
         id: index,
         type,
-        metricTypes: [""],
-        metrics: [""],
       };
-
-      if (type === WidgetType.Widget) {
-        newItem.metricMode = MetricModes.Expression;
-      }
       if (type === WidgetType.Tab) {
         newItem.h = 36;
         newItem.activedTabIndex = 0;
@@ -167,18 +161,12 @@ export const dashboardStore = defineStore({
         i: index,
         id,
         type,
-        metricTypes: [""],
-        metrics: [""],
       };
-      if (type === WidgetType.Widget) {
-        newItem.metricMode = MetricModes.Expression;
-      }
       if (type === WidgetType.Topology) {
         newItem.h = 32;
         newItem.graph = {
           showDepth: true,
         };
-        newItem.metricMode = MetricModes.Expression;
       }
       if (ControlsTypes.includes(type)) {
         newItem.h = 32;
diff --git a/src/store/modules/topology.ts b/src/store/modules/topology.ts
index dee037ae..1a399134 100644
--- a/src/store/modules/topology.ts
+++ b/src/store/modules/topology.ts
@@ -23,7 +23,6 @@ import { useDashboardStore } from "@/store/modules/dashboard";
 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";
 
@@ -226,9 +225,6 @@ export const topologyStore = defineStore({
     setNodeMetricValue(m: MetricVal) {
       this.nodeMetricValue = m;
     },
-    setNodeValue(m: MetricVal) {
-      this.nodeMetricValue = 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++) {
@@ -446,15 +442,6 @@ export const topologyStore = defineStore({
 
       return { calls, nodes };
     },
-    async getNodeMetricValue(param: { queryStr: string; conditions: { [key: 
string]: unknown } }) {
-      const res: AxiosResponse = await query(param);
-
-      if (res.data.errors) {
-        return res.data;
-      }
-      this.setNodeMetricValue(res.data.data);
-      return res.data;
-    },
     async getNodeExpressionValue(param: { queryStr: string; conditions: { 
[key: string]: unknown } }) {
       const res: AxiosResponse = await query(param);
 
@@ -464,38 +451,6 @@ export const topologyStore = defineStore({
 
       return res.data;
     },
-    async getLinkClientMetrics(linkClientMetrics: string[]) {
-      if (!linkClientMetrics.length) {
-        this.setLinkClientMetrics({});
-        return;
-      }
-      const idsC = this.calls.filter((i: Call) => 
i.detectPoints.includes("CLIENT")).map((b: Call) => b.id);
-      if (!idsC.length) {
-        return;
-      }
-      const param = await useQueryTopologyMetrics(linkClientMetrics, idsC);
-      const res = await this.getCallClientMetrics(param);
-
-      if (res.errors) {
-        ElMessage.error(res.errors);
-      }
-    },
-    async getLinkServerMetrics(linkServerMetrics: string[]) {
-      if (!linkServerMetrics.length) {
-        this.setLinkServerMetrics({});
-        return;
-      }
-      const idsS = this.calls.filter((i: Call) => 
i.detectPoints.includes("SERVER")).map((b: Call) => b.id);
-      if (!idsS.length) {
-        return;
-      }
-      const param = await useQueryTopologyMetrics(linkServerMetrics, idsS);
-      const res = await this.getCallServerMetrics(param);
-
-      if (res.errors) {
-        ElMessage.error(res.errors);
-      }
-    },
     async getLinkExpressions(expressions: string[], type: string) {
       if (!expressions.length) {
         this.setLinkServerMetrics({});
@@ -519,22 +474,6 @@ export const topologyStore = defineStore({
         this.setLinkClientMetrics(metrics);
       }
     },
-    async queryNodeMetrics(nodeMetrics: string[]) {
-      if (!nodeMetrics.length) {
-        this.setNodeMetricValue({});
-        return;
-      }
-      const ids = this.nodes.map((d: Node) => d.id);
-      if (!ids.length) {
-        return;
-      }
-      const param = await useQueryTopologyMetrics(nodeMetrics, ids);
-      const res = await this.getNodeMetricValue(param);
-
-      if (res.errors) {
-        ElMessage.error(res.errors);
-      }
-    },
     async queryNodeExpressions(expressions: string[]) {
       if (!expressions.length) {
         this.setNodeMetricValue({});
@@ -557,44 +496,6 @@ export const topologyStore = defineStore({
       const metrics = handleExpressionValues(res.data);
       this.setNodeMetricValue(metrics);
     },
-    async getLegendMetrics(param: { queryStr: string; conditions: { [key: 
string]: unknown } }) {
-      const res: AxiosResponse = await query(param);
-
-      if (res.data.errors) {
-        return res.data;
-      }
-      const data = res.data.data;
-      const metrics = Object.keys(data);
-      this.nodes = this.nodes.map((d: Node & Recordable) => {
-        for (const m of metrics) {
-          for (const val of data[m].values) {
-            if (d.id === val.id) {
-              d[m] = val.value;
-            }
-          }
-        }
-        return d;
-      });
-      return res.data;
-    },
-    async getCallServerMetrics(param: { queryStr: string; conditions: { [key: 
string]: unknown } }) {
-      const res: AxiosResponse = await query(param);
-
-      if (res.data.errors) {
-        return res.data;
-      }
-      this.setLinkServerMetrics(res.data.data);
-      return res.data;
-    },
-    async getCallClientMetrics(param: { queryStr: string; conditions: { [key: 
string]: unknown } }) {
-      const res: AxiosResponse = await query(param);
-
-      if (res.data.errors) {
-        return res.data;
-      }
-      this.setLinkClientMetrics(res.data.data);
-      return res.data;
-    },
     async getHierarchyServiceTopology() {
       const dashboardStore = useDashboardStore();
       const { currentService } = useSelectorStore();
diff --git a/src/types/dashboard.d.ts b/src/types/dashboard.d.ts
index be0bca58..5a24e53d 100644
--- a/src/types/dashboard.d.ts
+++ b/src/types/dashboard.d.ts
@@ -32,12 +32,9 @@ export interface LayoutConfig {
   h: number;
   i: string;
   type: string;
-  metricMode?: string;
   widget?: WidgetConfig;
   graph?: GraphConfig;
-  metrics?: string[];
   expressions?: string[];
-  metricTypes?: string[];
   typesOfMQE?: string[];
   children?: { name: string; children: LayoutConfig[]; expression?: string; 
enable?: boolean }[];
   activedTabIndex?: number;
@@ -77,7 +74,6 @@ export type Filters = {
 export type MetricConfigOpt = {
   unit?: string;
   label?: string;
-  calculation?: string;
   labelsIndex?: string;
   sortOrder?: string;
   topN?: number;
diff --git a/src/views/dashboard/List.vue b/src/views/dashboard/List.vue
index e57a92df..66285edc 100644
--- a/src/views/dashboard/List.vue
+++ b/src/views/dashboard/List.vue
@@ -304,6 +304,7 @@ limitations under the License. -->
 
   async function importTemplates(event: any) {
     const arr: any = await readFile(event);
+
     for (const item of arr) {
       const { layer, name, entity } = item.configuration;
       const index = dashboardStore.dashboards.findIndex(
@@ -359,6 +360,20 @@ limitations under the License. -->
       multipleTableRef.value!.clearSelection();
     }, 2000);
   }
+
+  function removeUnusedConfig(config: any) {
+    // remove `General` metrics config
+    delete config.metrics;
+    delete config.metricTypes;
+    delete config.metricMode;
+    delete config.linkServerMetrics;
+    delete config.linkClientMetrics;
+    delete config.nodeMetric;
+    if (([WidgetType.Topology] as string[]).includes(config.type)) {
+      delete config.legend;
+    }
+  }
+
   function optimizeTemplate(
     children: (LayoutConfig & {
       moved?: boolean;
@@ -390,17 +405,8 @@ limitations under the License. -->
       if (isEmptyObject(child.widget)) {
         delete child.widget;
       }
-      if (!(child.metrics && child.metrics.length && child.metrics[0])) {
-        delete child.metrics;
-      }
-      if (!(child.metricTypes && child.metricTypes.length && 
child.metricTypes[0])) {
-        delete child.metricTypes;
-      }
       if (child.metricConfig && child.metricConfig.length) {
         child.metricConfig.forEach((c, index) => {
-          if (!c.calculation) {
-            delete c.calculation;
-          }
           if (!c.unit) {
             delete c.unit;
           }
@@ -415,6 +421,7 @@ limitations under the License. -->
       if (!(child.metricConfig && child.metricConfig.length)) {
         delete child.metricConfig;
       }
+      removeUnusedConfig(child);
       if (child.type === WidgetType.Tab) {
         for (const item of child.children || []) {
           optimizeTemplate(item.children);
diff --git a/src/views/dashboard/Widget.vue b/src/views/dashboard/Widget.vue
index 1bbf7215..6a87e97e 100644
--- a/src/views/dashboard/Widget.vue
+++ b/src/views/dashboard/Widget.vue
@@ -32,10 +32,7 @@ limitations under the License. -->
         :config="{
           i: 0,
           ...graph,
-          metrics: config.metrics,
-          metricTypes: config.metricTypes,
           metricConfig: config.metricConfig,
-          metricMode: config.metricMode,
           expressions: config.expressions || [],
           typesOfMQE: typesOfMQE || [],
           subExpressions: config.subExpressions || [],
@@ -56,12 +53,10 @@ limitations under the License. -->
   import { useRoute } from "vue-router";
   import { useSelectorStore } from "@/store/modules/selectors";
   import { useDashboardStore } from "@/store/modules/dashboard";
-  import { useQueryProcessor, useSourceProcessor } from 
"@/hooks/useMetricsProcessor";
   import { useExpressionsQueryProcessor } from 
"@/hooks/useExpressionsProcessor";
   import graphs from "./graphs";
   import { EntityType } from "./data";
   import timeFormat from "@/utils/timeFormat";
-  import { MetricModes } from "./data";
 
   export default defineComponent({
     name: "WidgetPage",
@@ -132,37 +127,16 @@ limitations under the License. -->
         }
       }
       async function queryMetrics() {
-        const isExpression = config.value.metricMode === 
MetricModes.Expression;
-        if (isExpression) {
-          loading.value = true;
-          const params = await useExpressionsQueryProcessor({
-            metrics: config.value.expressions || [],
-            metricConfig: config.value.metricConfig || [],
-            subExpressions: config.value.subExpressions || [],
-          });
-
-          loading.value = false;
-          source.value = params.source || {};
-          typesOfMQE.value = params.typesOfMQE;
-          return;
-        }
-        const params = await useQueryProcessor({ ...config.value });
-        if (!params) {
-          source.value = {};
-          return;
-        }
         loading.value = true;
-        const json = await dashboardStore.fetchMetricValue(params);
-        loading.value = false;
-        if (!json) {
-          return;
-        }
-        const d = {
-          metrics: config.value.metrics || [],
-          metricTypes: config.value.metricTypes || [],
+        const params = await useExpressionsQueryProcessor({
+          metrics: config.value.expressions || [],
           metricConfig: config.value.metricConfig || [],
-        };
-        source.value = await useSourceProcessor(json, d);
+          subExpressions: config.value.subExpressions || [],
+        });
+
+        loading.value = false;
+        source.value = params.source || {};
+        typesOfMQE.value = params.typesOfMQE;
       }
       watch(
         () => appStoreWithOut.durationTime,
@@ -209,7 +183,7 @@ limitations under the License. -->
     height: 25px;
     line-height: 25px;
     text-align: center;
-    background-color: aliceblue;
+    background-color: var(--sw-config-header);
     font-size: $font-size-smaller;
     position: relative;
   }
diff --git a/src/views/dashboard/components/WidgetLink.vue 
b/src/views/dashboard/components/WidgetLink.vue
index 3660c504..fe159940 100644
--- a/src/views/dashboard/components/WidgetLink.vue
+++ b/src/views/dashboard/components/WidgetLink.vue
@@ -54,7 +54,6 @@ limitations under the License. -->
   import copy from "@/utils/copy";
   import { RefreshOptions } from "@/views/dashboard/data";
   import { TimeType } from "@/constants/data";
-  import { MetricModes } from "../data";
 
   const { t } = useI18n();
   const appStore = useAppStoreWithOut();
@@ -88,8 +87,7 @@ limitations under the License. -->
       step: appStore.durationRow.step,
       utc: appStore.utc,
     });
-    const { widget, graph, metrics, metricTypes, metricConfig, metricMode, 
expressions, typesOfMQE, subExpressions } =
-      dashboardStore.selectedGrid;
+    const { widget, graph, metricConfig, expressions, typesOfMQE, 
subExpressions } = dashboardStore.selectedGrid;
     const c = (metricConfig || []).map((d: any) => {
       const t: any = {};
       if (d.label) {
@@ -103,19 +101,13 @@ limitations under the License. -->
     const opt: any = {
       type: dashboardStore.selectedGrid.type,
       graph: graph,
-      metricMode,
       metricConfig: c,
       height: dashboardStore.selectedGrid.h * 20 + 60,
     };
-    if (metricMode === MetricModes.Expression) {
-      opt.expressions = expressions;
-      opt.typesOfMQE = typesOfMQE;
-      if (subExpressions && subExpressions.length) {
-        opt.subExpressions = subExpressions;
-      }
-    } else {
-      opt.metrics = metrics;
-      opt.metricTypes = metricTypes;
+    opt.expressions = expressions;
+    opt.typesOfMQE = typesOfMQE;
+    if (subExpressions && subExpressions.length) {
+      opt.subExpressions = subExpressions;
     }
     if (widget) {
       opt.widget = {
diff --git a/src/views/dashboard/configuration/Widget.vue 
b/src/views/dashboard/configuration/Widget.vue
index dd846a99..62248e94 100644
--- a/src/views/dashboard/configuration/Widget.vue
+++ b/src/views/dashboard/configuration/Widget.vue
@@ -34,11 +34,8 @@ limitations under the License. -->
             ...graph,
             legend: (dashboardStore.selectedGrid.graph || {}).legend,
             i: dashboardStore.selectedGrid.i,
-            metrics: dashboardStore.selectedGrid.metrics,
-            metricTypes: dashboardStore.selectedGrid.metricTypes,
             metricConfig: dashboardStore.selectedGrid.metricConfig,
             relatedTrace: dashboardStore.selectedGrid.relatedTrace,
-            metricMode: dashboardStore.selectedGrid.metricMode,
             expressions: dashboardStore.selectedGrid.expressions || [],
             typesOfMQE: dashboardStore.selectedGrid.typesOfMQE || [],
             subExpressions: dashboardStore.selectedGrid.subExpressions || [],
@@ -89,7 +86,6 @@ limitations under the License. -->
   import type { Option } from "@/types/app";
   import graphs from "../graphs";
   import CustomOptions from "./widget/index";
-  import { MetricModes } from "../data";
 
   export default defineComponent({
     name: "WidgetEdit",
@@ -142,23 +138,6 @@ limitations under the License. -->
 
       function applyConfig() {
         dashboardStore.setConfigPanel(false);
-        const { metricMode } = dashboardStore.selectedGrid;
-        let p = {};
-        if (metricMode === MetricModes.Expression) {
-          p = {
-            metrics: [],
-            metricTypes: [],
-          };
-        } else {
-          p = {
-            expressions: [],
-            typesOfMQE: [],
-          };
-        }
-        dashboardStore.selectWidget({
-          ...dashboardStore.selectedGrid,
-          ...p,
-        });
         dashboardStore.setConfigs(dashboardStore.selectedGrid);
       }
 
diff --git a/src/views/dashboard/configuration/widget/metric/Index.vue 
b/src/views/dashboard/configuration/widget/metric/Index.vue
index a58d2d9a..44cfc4aa 100644
--- a/src/views/dashboard/configuration/widget/metric/Index.vue
+++ b/src/views/dashboard/configuration/widget/metric/Index.vue
@@ -25,28 +25,20 @@ limitations under the License. -->
       :clearable="true"
     />
   </div>
-  <div>{{ t("metrics") }}</div>
   <div class="flex-h">
-    <el-switch
-      v-model="isExpression"
-      class="mb-5"
-      active-text="Expressions"
-      inactive-text="General"
-      size="small"
-      @change="changeMetricMode"
-    />
-    <div class="ml-5 link">
+    <div>{{ t("metrics") }}</div>
+    <div class="link">
       <a target="_blank" 
href="https://skywalking.apache.org/docs/main/next/en/api/metrics-query-expression/";>
         <Icon iconName="info_outline" size="middle" />
       </a>
     </div>
   </div>
-  <div v-if="isExpression && states.isList">
+  <div v-if="states.isList">
     <span class="title">{{ t("summary") }}</span>
     <span>{{ t("detail") }}</span>
   </div>
   <div v-for="(metric, index) in states.metrics" :key="index" class="mb-10">
-    <span v-if="isExpression">
+    <span>
       <div class="expression-param" contenteditable="true" 
@blur="changeExpression($event, index)">
         {{ metric }}
       </div>
@@ -59,24 +51,6 @@ limitations under the License. -->
         {{ states.subMetrics[index] }}
       </div>
     </span>
-    <span v-else>
-      <Selector
-        :value="metric"
-        :options="states.metricList"
-        size="small"
-        placeholder="Select a metric"
-        @change="changeMetrics(index, $event)"
-        class="selectors"
-      />
-      <Selector
-        :value="states.metricTypes[index]"
-        :options="states.metricTypeList[index]"
-        size="small"
-        :disabled="graph.type && !states.isList && index !== 0"
-        @change="changeMetricType(index, $event)"
-        class="selectors"
-      />
-    </span>
     <el-popover placement="top" :width="400" trigger="click">
       <template #reference>
         <span @click="setMetricConfig(index)">
@@ -88,7 +62,7 @@ limitations under the License. -->
     <span
       v-show="
         states.isList ||
-        [ProtocolTypes.ReadMetricsValues, 
ExpressionResultType.TIME_SERIES_VALUES as 
string].includes(states.metricTypes[0])
+        [ExpressionResultType.TIME_SERIES_VALUES as 
string].includes(states.metricTypes[0])
       "
     >
       <Icon
@@ -100,13 +74,13 @@ limitations under the License. -->
       />
       <Icon class="cp" iconName="remove_circle_outline" size="middle" 
@click="deleteMetric(index)" />
     </span>
-    <div v-if="(states.tips || [])[index] && isExpression" class="ml-10 red 
sm">
+    <div v-if="(states.tips || [])[index]" class="ml-10 red sm">
       {{ states.tips[index] }}
     </div>
-    <div v-if="(errors || [])[index] && isExpression" class="ml-10 red sm">
+    <div v-if="(errors || [])[index]" class="ml-10 red sm">
       {{ (errors || [])[index] }}
     </div>
-    <div v-if="(subErrors || [])[index] && isExpression" class="ml-10 red sm">
+    <div v-if="(subErrors || [])[index]" class="ml-10 red sm">
       {{ (subErrors || [])[index] }}
     </div>
   </div>
@@ -128,20 +102,14 @@ limitations under the License. -->
   import type { Option } from "@/types/app";
   import { useDashboardStore } from "@/store/modules/dashboard";
   import {
-    MetricTypes,
     ListChartTypes,
     DefaultGraphConfig,
     EntityType,
     ChartTypes,
     PodsChartTypes,
-    MetricsType,
-    ProtocolTypes,
     ExpressionResultType,
-    MetricModes,
-  } from "../../../data";
-  import { ElMessage } from "element-plus";
+  } from "@/views/dashboard/data";
   import Icon from "@/components/Icon.vue";
-  import { useQueryProcessor, useSourceProcessor } from 
"@/hooks/useMetricsProcessor";
   import { useExpressionsQueryProcessor } from 
"@/hooks/useExpressionsProcessor";
   import { useI18n } from "vue-i18n";
   import type { DashboardItem, MetricConfigOpt } from "@/types/dashboard";
@@ -160,16 +128,11 @@ limitations under the License. -->
     },
   });
   const dashboardStore = useDashboardStore();
-  const isExpression = ref<boolean>(dashboardStore.selectedGrid.metricMode === 
MetricModes.Expression);
-  const metrics = computed(
-    () => (isExpression.value ? dashboardStore.selectedGrid.expressions : 
dashboardStore.selectedGrid.metrics) || [],
-  );
-  const subMetrics = computed(() => (isExpression.value ? 
dashboardStore.selectedGrid.subExpressions : []) || []);
-  const subMetricTypes = computed(() => (isExpression.value ? 
dashboardStore.selectedGrid.subTypesOfMQE : []) || []);
+  const metrics = computed(() => dashboardStore.selectedGrid.expressions || 
[]);
+  const subMetrics = computed(() => dashboardStore.selectedGrid.subExpressions 
|| []);
+  const subMetricTypes = computed(() => 
dashboardStore.selectedGrid.subTypesOfMQE || []);
   const graph = computed(() => dashboardStore.selectedGrid.graph || {});
-  const metricTypes = computed(
-    () => (isExpression.value ? dashboardStore.selectedGrid.typesOfMQE : 
dashboardStore.selectedGrid.metricTypes) || [],
-  );
+  const typesOfMQE = computed(() => dashboardStore.selectedGrid.typesOfMQE || 
[]);
   const states = reactive<{
     metrics: string[];
     subMetrics: string[];
@@ -177,17 +140,15 @@ limitations under the License. -->
     metricTypes: string[];
     metricTypeList: Option[][];
     isList: boolean;
-    metricList: (Option & { type: string })[];
     dashboardName: string;
     dashboardList: ((DashboardItem & { label: string; value: string }) | 
any)[];
     tips: string[];
     subTips: string[];
   }>({
     metrics: metrics.value.length ? metrics.value : [""],
-    metricTypes: metricTypes.value.length ? metricTypes.value : [""],
+    metricTypes: typesOfMQE.value.length ? typesOfMQE.value : [""],
     metricTypeList: [],
     isList: false,
-    metricList: [],
     dashboardName: graph.value.dashboardName,
     dashboardList: [{ label: "", value: "" }],
     tips: [],
@@ -199,16 +160,13 @@ limitations under the License. -->
     unit: "",
     label: "",
     labelsIndex: "",
-    calculation: "",
     sortOrder: "DES",
   });
 
   states.isList = ListChartTypes.includes(graph.value.type);
   const defaultLen = ref<number>(states.isList ? 5 : 20);
-  const backupMetricConfig = ref<MetricConfigOpt[]>([]);
 
   setDashboards();
-  setMetricType();
 
   const setVisTypes = computed(() => {
     let graphs = [];
@@ -223,70 +181,6 @@ limitations under the License. -->
     return graphs;
   });
 
-  async function setMetricType(chart?: any) {
-    const g = chart || dashboardStore.selectedGrid.graph || {};
-    let arr: any[] = states.metricList;
-    if (!chart) {
-      const json = await dashboardStore.fetchMetricList();
-      if (json.errors) {
-        ElMessage.error(json.errors);
-        return;
-      }
-      arr = json.data.metrics;
-    }
-    states.metricList = (arr || []).filter((d: { type: string }) => {
-      if (states.isList) {
-        if (d.type === MetricsType.REGULAR_VALUE || d.type === 
MetricsType.LABELED_VALUE) {
-          return d;
-        }
-      } else if (g.type === "Table") {
-        if (d.type === MetricsType.LABELED_VALUE || d.type === 
MetricsType.REGULAR_VALUE) {
-          return d;
-        }
-      } else {
-        return d;
-      }
-    });
-    if (isExpression.value) {
-      if (states.metrics && states.metrics[0]) {
-        queryMetrics();
-      } else {
-        emit("update", {});
-      }
-      return;
-    }
-    const metrics: any = states.metricList.filter((d: { value: string; type: 
string }) =>
-      states.metrics.includes(d.value),
-    );
-
-    if (metrics.length) {
-      // keep states.metrics index
-      const m = metrics.map((d: { value: string }) => d.value);
-      states.metrics = states.metrics.filter((d) => m.includes(d));
-    } else {
-      states.metrics = [""];
-      states.metricTypes = [""];
-    }
-    dashboardStore.selectWidget({
-      ...dashboardStore.selectedGrid,
-      metrics: states.metrics,
-      metricTypes: states.metricTypes,
-      graph: g,
-    });
-    states.metricTypeList = [];
-    for (const metric of metrics) {
-      if (states.metrics.includes(metric.value)) {
-        const arr = setMetricTypeList(metric.type);
-        states.metricTypeList.push(arr);
-      }
-    }
-    if (states.metrics && states.metrics[0]) {
-      queryMetrics();
-    } else {
-      emit("update", {});
-    }
-  }
-
   function setDashboards(type?: string) {
     const chart = type || (dashboardStore.selectedGrid.graph && 
dashboardStore.selectedGrid.graph.type);
     const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
@@ -308,6 +202,11 @@ limitations under the License. -->
     }, []);
 
     states.dashboardList = arr.length ? arr : [{ label: "", value: "" }];
+    if (states.metrics && states.metrics[0]) {
+      queryMetrics();
+    } else {
+      emit("update", {});
+    }
   }
 
   function changeChartType(item: Option) {
@@ -316,8 +215,6 @@ limitations under the License. -->
     if (states.isList) {
       dashboardStore.selectWidget({
         ...dashboardStore.selectedGrid,
-        metrics: [""],
-        metricTypes: [""],
         expressions: [""],
         typesOfMQE: [""],
       });
@@ -326,97 +223,20 @@ limitations under the License. -->
       defaultLen.value = 5;
     }
 
-    if (isExpression.value) {
-      dashboardStore.selectWidget({
-        ...dashboardStore.selectedGrid,
-        graph: chart,
-      });
-    } else {
-      setMetricType(chart);
-    }
-    setDashboards(chart.type);
-    states.dashboardName = "";
-    defaultLen.value = 10;
-  }
-
-  function changeMetrics(index: number, arr: (Option & { type: string })[] | 
any) {
-    if (!arr.length) {
-      states.metricTypeList = [];
-      states.metricTypes = [];
-      dashboardStore.selectWidget({
-        ...dashboardStore.selectedGrid,
-        ...{ metricTypes: states.metricTypes, metrics: states.metrics },
-      });
-      return;
-    }
-    states.metrics[index] = arr[0].value;
-    const typeOfMetrics = arr[0].type;
-
-    states.metricTypeList[index] = setMetricTypeList(typeOfMetrics);
-    states.metricTypes[index] = MetricTypes[typeOfMetrics][0].value;
     dashboardStore.selectWidget({
       ...dashboardStore.selectedGrid,
-      ...{ metricTypes: states.metricTypes, metrics: states.metrics },
+      graph: chart,
     });
-    if (states.isList) {
-      return;
-    }
-    queryMetrics();
+    setDashboards(chart.type);
+    states.dashboardName = "";
+    defaultLen.value = 10;
   }
 
-  function changeMetricType(index: number, opt: Option[] | any) {
-    const metric = states.metricList.filter((d: Option) => 
states.metrics[index] === d.value)[0] || {};
-    const l = setMetricTypeList(metric.type);
-    if (states.isList) {
-      states.metricTypes[index] = opt[0].value;
-      states.metricTypeList[index] = l;
-    } else {
-      states.metricTypes = states.metricTypes.map((d: string) => {
-        d = opt[0].value;
-        return d;
-      });
-      states.metricTypeList = states.metricTypeList.map((d: Option[]) => {
-        d = l;
-
-        return d;
-      });
-    }
-    dashboardStore.selectWidget({
-      ...dashboardStore.selectedGrid,
-      ...{ metricTypes: states.metricTypes },
-    });
-    if (states.isList) {
-      return;
-    }
-    queryMetrics();
-  }
   async function queryMetrics() {
     if (states.isList) {
       return;
     }
-    if (isExpression.value) {
-      queryMetricsWithExpressions();
-      return;
-    }
-    const { metricConfig, metricTypes, metrics } = dashboardStore.selectedGrid;
-    if (!(metrics && metrics[0] && metricTypes && metricTypes[0])) {
-      return emit("update", {});
-    }
-    const params = useQueryProcessor({ ...states, metricConfig });
-    if (!params) {
-      emit("update", {});
-      return;
-    }
-
-    emit("loading", true);
-    const json = await dashboardStore.fetchMetricValue(params);
-    emit("loading", false);
-    if (json.errors) {
-      ElMessage.error(json.errors);
-      return;
-    }
-    const source = useSourceProcessor(json, { ...states, metricConfig });
-    emit("update", source);
+    queryMetricsWithExpressions();
   }
 
   async function queryMetricsWithExpressions() {
@@ -432,7 +252,6 @@ limitations under the License. -->
       ...dashboardStore.selectedGrid,
       typesOfMQE: states.metricTypes,
     });
-
     emit("update", params.source || {});
   }
 
@@ -454,43 +273,32 @@ limitations under the License. -->
   function addMetric() {
     states.metrics.push("");
     states.tips.push("");
-    if (isExpression.value && states.isList) {
+    if (states.isList) {
       states.subMetrics.push("");
       states.subTips.push("");
     }
 
     if (!states.isList) {
       states.metricTypes.push(states.metricTypes[0]);
-      if (!isExpression.value) {
-        states.metricTypeList.push(states.metricTypeList[0]);
-      }
       return;
     }
     states.metricTypes.push("");
-    if (isExpression.value && states.isList) {
-      states.subMetricTypes.push("");
-    }
   }
   function deleteMetric(index: number) {
     if (states.metrics.length === 1) {
       states.metrics = [""];
       states.metricTypes = [""];
       states.tips = [""];
-      let v = {};
-      if (isExpression.value) {
-        v = { typesOfMQE: states.metricTypes, expressions: states.metrics };
-        if (states.isList) {
-          states.subMetrics = [""];
-          states.subMetricTypes = [""];
-          states.subTips = [""];
-          v = {
-            ...v,
-            subTypesOfMQE: states.subMetricTypes,
-            subExpressions: states.subMetrics,
-          };
-        }
-      } else {
-        v = { metricTypes: states.metricTypes, metrics: states.metrics };
+      let v: any = { typesOfMQE: states.metricTypes, expressions: 
states.metrics };
+      if (states.isList) {
+        states.subMetrics = [""];
+        states.subMetricTypes = [""];
+        states.subTips = [""];
+        v = {
+          ...v,
+          subTypesOfMQE: states.subMetricTypes,
+          subExpressions: states.subMetrics,
+        };
       }
       dashboardStore.selectWidget({
         ...dashboardStore.selectedGrid,
@@ -505,37 +313,26 @@ limitations under the License. -->
     const config = dashboardStore.selectedGrid.metricConfig || [];
     const metricConfig = config[index] ? config.splice(index, 1) : config;
     let p = {};
-    if (isExpression.value) {
-      if (states.isList) {
-        states.subMetrics.splice(index, 1);
-        states.subMetricTypes.splice(index, 1);
-        states.subTips.splice(index, 1);
-        p = {
-          ...p,
-          typesOfMQE: states.metricTypes,
-          expressions: states.metrics,
-          subTypesOfMQE: states.subMetricTypes,
-          subExpressions: states.subMetrics,
-        };
-      }
-    } else {
-      p = { metricTypes: states.metricTypes, metrics: states.metrics };
+    if (states.isList) {
+      states.subMetrics.splice(index, 1);
+      states.subMetricTypes.splice(index, 1);
+      states.subTips.splice(index, 1);
+      p = {
+        ...p,
+        typesOfMQE: states.metricTypes,
+        expressions: states.metrics,
+        subTypesOfMQE: states.subMetricTypes,
+        subExpressions: states.subMetrics,
+      };
     }
     dashboardStore.selectWidget({
       ...dashboardStore.selectedGrid,
       ...p,
       metricConfig,
     });
+    queryMetrics();
   }
-  function setMetricTypeList(type: string) {
-    if (type !== MetricsType.REGULAR_VALUE) {
-      return MetricTypes[type];
-    }
-    if (states.isList || graph.value.type === "Table") {
-      return [MetricTypes.REGULAR_VALUE[0], MetricTypes.REGULAR_VALUE[1]];
-    }
-    return MetricTypes[type];
-  }
+
   function setMetricConfig(index: number) {
     const n = {
       unit: "",
@@ -553,20 +350,6 @@ limitations under the License. -->
       ...dashboardStore.selectedGrid.metricConfig[index],
     };
   }
-  function changeMetricMode() {
-    states.metrics = metrics.value.length ? metrics.value : [""];
-    states.subMetrics = subMetrics.value.length ? subMetrics.value : [""];
-    states.metricTypes = metricTypes.value.length ? metricTypes.value : [""];
-    states.subMetricTypes = subMetricTypes.value.length ? subMetricTypes.value 
: [""];
-    const config = dashboardStore.selectedGrid.metricConfig;
-    dashboardStore.selectWidget({
-      ...dashboardStore.selectedGrid,
-      metricMode: isExpression.value ? MetricModes.Expression : 
MetricModes.General,
-      metricConfig: backupMetricConfig.value,
-    });
-    backupMetricConfig.value = config;
-    queryMetrics();
-  }
   async function changeExpression(event: any, index: number) {
     const params = (event.target.textContent || "").replace(/\s+/g, "");
 
@@ -651,5 +434,6 @@ limitations under the License. -->
   .link {
     cursor: pointer;
     color: $active-color;
+    padding-left: 2px;
   }
 </style>
diff --git a/src/views/dashboard/configuration/widget/metric/Standard.vue 
b/src/views/dashboard/configuration/widget/metric/Standard.vue
index 5b88699b..6b8de5b6 100644
--- a/src/views/dashboard/configuration/widget/metric/Standard.vue
+++ b/src/views/dashboard/configuration/widget/metric/Standard.vue
@@ -28,7 +28,7 @@ limitations under the License. -->
         "
       />
     </div>
-    <div class="item mb-10" v-if="hasLabel || isExpression">
+    <div class="item mb-10">
       <span class="label">{{ t("labels") }}</span>
       <el-input
         class="input"
@@ -42,7 +42,7 @@ limitations under the License. -->
         "
       />
     </div>
-    <div class="item mb-10" v-if="isList && isExpression">
+    <div class="item mb-10" v-if="isList">
       <span class="label">{{ t("detailLabel") }}</span>
       <el-input
         class="input"
@@ -56,30 +56,6 @@ limitations under the License. -->
         "
       />
     </div>
-    <div class="item mb-10" 
v-if="[ProtocolTypes.ReadLabeledMetricsValues].includes(metricType) && 
!isExpression">
-      <span class="label">{{ t("labelsIndex") }}</span>
-      <el-input
-        class="input"
-        v-model="currentMetric.labelsIndex"
-        size="small"
-        placeholder="auto"
-        @change="
-          updateConfig(index, {
-            labelsIndex: encodeURIComponent(currentMetric.labelsIndex || ''),
-          })
-        "
-      />
-    </div>
-    <div class="item mb-10" v-show="!isExpression">
-      <span class="label">{{ t("aggregation") }}</span>
-      <SelectSingle
-        :value="currentMetric.calculation"
-        :options="CalculationOpts"
-        @change="changeConfigs(index, { calculation: $event })"
-        class="selectors"
-        :clearable="true"
-      />
-    </div>
     <div class="item mb-10" v-show="isTopn">
       <span class="label">{{ t("sortOrder") }}</span>
       <SelectSingle
@@ -108,10 +84,9 @@ limitations under the License. -->
   import { ref, watch, computed } from "vue";
   import type { PropType } from "vue";
   import { useI18n } from "vue-i18n";
-  import { SortOrder, CalculationOpts, MetricModes } from "../../../data";
+  import { SortOrder, ExpressionResultType, ListChartTypes } from 
"@/views/dashboard/data";
   import { useDashboardStore } from "@/store/modules/dashboard";
   import type { MetricConfigOpt } from "@/types/dashboard";
-  import { ListChartTypes, ProtocolTypes } from "../../../data";
 
   /*global defineEmits, defineProps */
   const props = defineProps({
@@ -124,30 +99,17 @@ limitations under the License. -->
   const { t } = useI18n();
   const emit = defineEmits(["update"]);
   const dashboardStore = useDashboardStore();
-  const isExpression = ref<boolean>(dashboardStore.selectedGrid.metricMode === 
MetricModes.Expression);
   const currentMetric = ref<MetricConfigOpt>({
     ...props.currentMetricConfig,
     topN: props.currentMetricConfig.topN || 10,
   });
-  const metricTypes = computed(
-    () => (isExpression.value ? dashboardStore.selectedGrid.typesOfMQE : 
dashboardStore.selectedGrid.metricTypes) || [],
-  );
-  const metricType = computed(() => metricTypes.value[props.index]);
-  const hasLabel = computed(() => {
-    const graph = dashboardStore.selectedGrid.graph || {};
-    return (
-      ListChartTypes.includes(graph.type) ||
-      [ProtocolTypes.ReadLabeledMetricsValues, 
ProtocolTypes.ReadMetricsValues].includes(metricType.value)
-    );
-  });
+  const metricTypes = computed(() => dashboardStore.selectedGrid.typesOfMQE || 
[]);
   const isList = computed(() => {
     const graph = dashboardStore.selectedGrid.graph || {};
     return ListChartTypes.includes(graph.type);
   });
   const isTopn = computed(() =>
-    [ProtocolTypes.SortMetrics, ProtocolTypes.ReadSampledRecords, 
ProtocolTypes.ReadRecords].includes(
-      metricTypes.value[props.index],
-    ),
+    [ExpressionResultType.RECORD_LIST, 
ExpressionResultType.SORTED_LIST].includes(metricTypes.value[props.index]),
   );
 
   function updateConfig(index: number, param: { [key: string]: string }) {
@@ -170,7 +132,6 @@ limitations under the License. -->
   watch(
     () => props.currentMetricConfig,
     () => {
-      isExpression.value = dashboardStore.selectedGrid.metricMode === 
MetricModes.Expression;
       currentMetric.value = {
         ...props.currentMetricConfig,
         topN: Number(props.currentMetricConfig.topN) || 10,
diff --git a/src/views/dashboard/controls/Widget.vue 
b/src/views/dashboard/controls/Widget.vue
index f7ac3812..49078a07 100644
--- a/src/views/dashboard/controls/Widget.vue
+++ b/src/views/dashboard/controls/Widget.vue
@@ -51,15 +51,12 @@ limitations under the License. -->
         :data="state.source"
         :config="{
           ...data.graph,
-          metrics: data.metrics || [''],
-          metricTypes: data.metricTypes || [''],
           i: data.i,
           id: data.id,
           metricConfig: data.metricConfig || [],
           filters: data.filters || {},
           relatedTrace: data.relatedTrace || {},
           associate: data.associate || [],
-          metricMode: data.metricMode,
           expressions: data.expressions || [],
           typesOfMQE: typesOfMQE || [],
           subExpressions: data.subExpressions || [],
@@ -81,12 +78,10 @@ limitations under the License. -->
   import { useSelectorStore } from "@/store/modules/selectors";
   import graphs from "../graphs";
   import { useI18n } from "vue-i18n";
-  import { useQueryProcessor, useSourceProcessor } from 
"@/hooks/useMetricsProcessor";
   import { useExpressionsQueryProcessor } from 
"@/hooks/useExpressionsProcessor";
   import { EntityType, ListChartTypes } from "../data";
   import type { EventParams } from "@/types/dashboard";
   import getDashboard from "@/hooks/useDashboardsSession";
-  import { MetricModes } from "../data";
 
   const props = {
     data: {
@@ -121,38 +116,15 @@ limitations under the License. -->
       }
 
       async function queryMetrics() {
-        const isExpression = props.data.metricMode === MetricModes.Expression;
-
-        if (isExpression) {
-          loading.value = true;
-          const e = {
-            metrics: props.data.expressions || [],
-            metricConfig: props.data.metricConfig || [],
-          };
-          const params = (await useExpressionsQueryProcessor(e)) || {};
-          loading.value = false;
-          state.source = params.source || {};
-          typesOfMQE.value = params.typesOfMQE;
-          return;
-        }
-        const params = await useQueryProcessor({ ...props.data });
-
-        if (!params) {
-          state.source = {};
-          return;
-        }
         loading.value = true;
-        const json = await dashboardStore.fetchMetricValue(params);
-        loading.value = false;
-        if (!json) {
-          return;
-        }
-        const d = {
-          metrics: props.data.metrics || [],
-          metricTypes: props.data.metricTypes || [],
+        const e = {
+          metrics: props.data.expressions || [],
           metricConfig: props.data.metricConfig || [],
         };
-        state.source = await useSourceProcessor(json, d);
+        const params = (await useExpressionsQueryProcessor(e)) || {};
+        loading.value = false;
+        state.source = params.source || {};
+        typesOfMQE.value = params.typesOfMQE;
       }
 
       function removeWidget() {
@@ -188,7 +160,7 @@ limitations under the License. -->
         dashboardStore.selectWidget(props.data);
       }
       watch(
-        () => [props.data.metricTypes, props.data.metrics, 
props.data.expressions],
+        () => props.data.expressions,
         () => {
           if (!dashboardStore.selectedGrid) {
             return;
diff --git a/src/views/dashboard/data.ts b/src/views/dashboard/data.ts
index 7cb2d458..c691ba02 100644
--- a/src/views/dashboard/data.ts
+++ b/src/views/dashboard/data.ts
@@ -34,29 +34,6 @@ export const ChartTypes = [
   { label: "Endpoint List", value: "EndpointList" },
   { label: "Instance List", value: "InstanceList" },
 ];
-export const MetricChartType: any = {
-  readMetricsValue: [{ label: "Card", value: "Card" }],
-  readMetricsValues: [
-    { label: "Bar", value: "Bar" },
-    { label: "Line", value: "Line" },
-    { label: "Area", value: "Area" },
-  ],
-  sortMetrics: [{ label: "Top List", value: "TopList" }],
-  readLabeledMetricsValues: [{ label: "Line", value: "Line" }],
-  readHeatMap: [{ label: "Heat Map", value: "HeatMap" }],
-  readSampledRecords: [{ label: "Top List", value: "TopList" }],
-  readRecords: [{ label: "Top List", value: "TopList" }],
-};
-export enum ProtocolTypes {
-  ReadRecords = "readRecords",
-  ReadSampledRecords = "readSampledRecords",
-  SortMetrics = "sortMetrics",
-  ReadLabeledMetricsValues = "readLabeledMetricsValues",
-  ReadHeatMap = "readHeatMap",
-  ReadMetricsValues = "readMetricsValues",
-  ReadMetricsValue = "readMetricsValue",
-}
-
 export enum ExpressionResultType {
   UNKNOWN = "UNKNOWN",
   SINGLE_VALUE = "SINGLE_VALUE",
@@ -124,34 +101,6 @@ export const DefaultGraphConfig: { [key: string]: any } = {
   },
 };
 
-export enum MetricsType {
-  UNKNOWN = "UNKNOWN",
-  REGULAR_VALUE = "REGULAR_VALUE",
-  LABELED_VALUE = "LABELED_VALUE",
-  HEATMAP = "HEATMAP",
-  SAMPLED_RECORD = "SAMPLED_RECORD",
-}
-export const MetricTypes: {
-  [key: string]: Array<{ label: string; value: string }>;
-} = {
-  REGULAR_VALUE: [
-    { label: "read all values in the duration", value: "readMetricsValues" },
-    {
-      label: "read the single value in the duration",
-      value: "readMetricsValue",
-    },
-    { label: "get sorted top N values", value: "sortMetrics" },
-  ],
-  LABELED_VALUE: [
-    {
-      label: "read all values of labels in the duration",
-      value: "readLabeledMetricsValues",
-    },
-  ],
-  HEATMAP: [{ label: "read heatmap values in the duration", value: 
"readHeatMap" }],
-  SAMPLED_RECORD: [{ label: "get sorted topN values", value: "readRecords" }],
-};
-
 export enum MetricCatalog {
   SERVICE = "Service",
   SERVICE_INSTANCE = "ServiceInstance",
@@ -292,19 +241,6 @@ export const ScopeType = [
   { value: "Endpoint", label: "Endpoint", key: 3 },
   { value: "ServiceInstance", label: "Service Instance", key: 3 },
 ];
-export const LegendConditions = [
-  { label: "&&", value: "and" },
-  { label: "||", value: "or" },
-];
-export const MetricConditions = [
-  { label: ">", value: ">" },
-  { label: "<", value: "<" },
-];
-export enum LegendOpt {
-  NAME = "name",
-  VALUE = "value",
-  CONDITION = "condition",
-}
 export const DepthList = [1, 2, 3, 4, 5].map((item: number) => ({
   value: item,
   label: String(item),
@@ -329,24 +265,6 @@ export const TextColors: { [key: string]: string } = {
   purple: "#bf99f8",
 };
 
-export const CalculationOpts = [
-  { label: "Percentage", value: "percentage" },
-  { label: "Apdex", value: "apdex" },
-  { label: "Avg-preview", value: "average" },
-  { label: "Percentage + Avg-preview", value: "percentageAvg" },
-  { label: "Apdex + Avg-preview", value: "apdexAvg" },
-  { label: "Byte to KB", value: "byteToKB" },
-  { label: "Byte to MB", value: "byteToMB" },
-  { label: "Byte to GB", value: "byteToGB" },
-  {
-    label: "Milliseconds to YYYY-MM-DD HH:mm:ss",
-    value: "convertMilliseconds",
-  },
-  { label: "Seconds to YYYY-MM-DD HH:mm:ss", value: "convertSeconds" },
-  { label: "Milliseconds to seconds", value: "msTos" },
-  { label: "Seconds to days", value: "secondToDay" },
-  { label: "Nanoseconds to milliseconds", value: "nanosecondToMillisecond" },
-];
 export const RefIdTypes = [
   { label: "Trace ID", value: "traceId" },
   { label: "None", value: "none" },
@@ -357,10 +275,6 @@ export const RefreshOptions = [
   { label: "Last 7 days", value: "7", step: "DAY" },
 ];
 
-export enum MetricModes {
-  Expression = "Expression",
-  General = "General",
-}
 export enum CallTypes {
   Server = "SERVER",
   Client = "CLIENT",
diff --git a/src/views/dashboard/graphs/EndpointList.vue 
b/src/views/dashboard/graphs/EndpointList.vue
index 4f07cd6d..3831b043 100644
--- a/src/views/dashboard/graphs/EndpointList.vue
+++ b/src/views/dashboard/graphs/EndpointList.vue
@@ -40,8 +40,7 @@ limitations under the License. -->
           :config="{
             ...config,
             metricConfig,
-            metricTypes,
-            metricMode,
+            typesOfMQE,
           }"
           v-if="colMetrics.length"
         />
@@ -58,9 +57,8 @@ limitations under the License. -->
   import type { EndpointListConfig } from "@/types/dashboard";
   import type { Endpoint } from "@/types/selector";
   import { useDashboardStore } from "@/store/modules/dashboard";
-  import { useQueryPodsMetrics, usePodsSource } from 
"@/hooks/useMetricsProcessor";
   import { useExpressionsQueryPodsMetrics } from 
"@/hooks/useExpressionsProcessor";
-  import { EntityType, MetricModes } from "../data";
+  import { EntityType } from "../data";
   import router from "@/router";
   import getDashboard from "@/hooks/useDashboardsSession";
   import type { MetricConfigOpt } from "@/types/dashboard";
@@ -75,9 +73,6 @@ limitations under the License. -->
       type: Object as PropType<
         EndpointListConfig & {
           i: string;
-          metrics: string[];
-          metricTypes: string[];
-          metricMode: string;
           expressions: string[];
           typesOfMQE: string[];
           subExpressions: string[];
@@ -85,8 +80,6 @@ limitations under the License. -->
         } & { metricConfig: MetricConfigOpt[] }
       >,
       default: () => ({
-        metrics: [],
-        metricTypes: [],
         dashboardName: "",
         fontSize: 12,
         i: "",
@@ -106,8 +99,7 @@ limitations under the License. -->
   const colMetrics = ref<string[]>([]);
   const colSubMetrics = ref<string[]>([]);
   const metricConfig = ref<MetricConfigOpt[]>(props.config.metricConfig || []);
-  const metricTypes = ref<string[]>(props.config.metricTypes || []);
-  const metricMode = ref<string>(props.config.metricMode);
+  const typesOfMQE = ref<string[]>(props.config.typesOfMQE || []);
 
   if (props.needQuery) {
     queryEndpoints();
@@ -138,34 +130,7 @@ limitations under the License. -->
         merge: d.merge,
       };
     });
-    if (props.config.metricMode === MetricModes.Expression) {
-      queryEndpointExpressions(currentPods);
-      return;
-    }
-    const metrics = props.config.metrics || [];
-    const types = props.config.metricTypes || [];
-    if (metrics.length && metrics[0] && types.length && types[0]) {
-      const params = await useQueryPodsMetrics(currentPods, props.config, 
EntityType[2].value);
-      const json = await dashboardStore.fetchMetricValue(params);
-
-      if (json.errors) {
-        ElMessage.error(json.errors);
-        return;
-      }
-      const { data, names, metricConfigArr, metricTypesArr } = 
usePodsSource(currentPods, json, {
-        ...props.config,
-        metricConfig: metricConfig.value,
-      });
-      endpoints.value = data;
-      colMetrics.value = names;
-      metricTypes.value = metricTypesArr;
-      metricConfig.value = metricConfigArr;
-      return;
-    }
-    endpoints.value = currentPods;
-    colMetrics.value = [];
-    metricTypes.value = [];
-    metricConfig.value = [];
+    queryEndpointExpressions(currentPods);
   }
   async function queryEndpointExpressions(currentPods: Endpoint[]) {
     const expressions = props.config.expressions || [];
@@ -180,8 +145,8 @@ limitations under the License. -->
       endpoints.value = params.data;
       colMetrics.value = params.names;
       colSubMetrics.value = params.subNames;
-      metricTypes.value = params.metricTypesArr;
       metricConfig.value = params.metricConfigArr;
+      typesOfMQE.value = params.metricTypesArr;
       emit("expressionTips", { tips: params.expressionsTips, subTips: 
params.subExpressionsTips });
 
       return;
@@ -189,8 +154,8 @@ limitations under the License. -->
     endpoints.value = currentPods;
     colMetrics.value = [];
     colSubMetrics.value = [];
-    metricTypes.value = [];
     metricConfig.value = [];
+    typesOfMQE.value = [];
     emit("expressionTips", [], []);
   }
   function clickEndpoint(scope: any) {
@@ -212,19 +177,15 @@ limitations under the License. -->
   }
   watch(
     () => [
-      ...(props.config.metricTypes || []),
-      ...(props.config.metrics || []),
       ...(props.config.metricConfig || []),
       ...(props.config.expressions || []),
       ...(props.config.subExpressions || []),
-      props.config.metricMode,
     ],
     (data, old) => {
       if (JSON.stringify(data) === JSON.stringify(old)) {
         return;
       }
       metricConfig.value = props.config.metricConfig;
-      metricMode.value = props.config.metricMode;
       queryEndpointMetrics(endpoints.value);
     },
   );
diff --git a/src/views/dashboard/graphs/InstanceList.vue 
b/src/views/dashboard/graphs/InstanceList.vue
index 4c9b4d30..f54c8c53 100644
--- a/src/views/dashboard/graphs/InstanceList.vue
+++ b/src/views/dashboard/graphs/InstanceList.vue
@@ -39,8 +39,7 @@ limitations under the License. -->
           :config="{
             ...config,
             metricConfig,
-            metricTypes,
-            metricMode,
+            typesOfMQE,
           }"
           v-if="colMetrics.length"
         />
@@ -85,9 +84,8 @@ limitations under the License. -->
   import { useDashboardStore } from "@/store/modules/dashboard";
   import type { InstanceListConfig } from "@/types/dashboard";
   import type { Instance } from "@/types/selector";
-  import { useQueryPodsMetrics, usePodsSource } from 
"@/hooks/useMetricsProcessor";
   import { useExpressionsQueryPodsMetrics } from 
"@/hooks/useExpressionsProcessor";
-  import { EntityType, MetricModes } from "../data";
+  import { EntityType } from "../data";
   import router from "@/router";
   import getDashboard from "@/hooks/useDashboardsSession";
   import type { MetricConfigOpt } from "@/types/dashboard";
@@ -100,9 +98,7 @@ limitations under the License. -->
         InstanceListConfig & {
           i: string;
           metrics: string[];
-          metricTypes: string[];
           isEdit: boolean;
-          metricMode: string;
           expressions: string[];
           typesOfMQE: string[];
           subExpressions: string[];
@@ -114,7 +110,7 @@ limitations under the License. -->
         fontSize: 12,
         i: "",
         metrics: [],
-        metricTypes: [],
+        typesOfMQE: [],
       }),
     },
     intervalTime: { type: Array as PropType<string[]>, default: () => [] },
@@ -131,9 +127,9 @@ limitations under the License. -->
   const colMetrics = ref<string[]>([]);
   const colSubMetrics = ref<string[]>([]);
   const metricConfig = ref<MetricConfigOpt[]>(props.config.metricConfig || []);
-  const metricTypes = ref<string[]>(props.config.metricTypes || []);
   const pods = ref<Instance[]>([]); // all instances
-  const metricMode = ref<string>(props.config.metricMode);
+  const typesOfMQE = ref<string[]>(props.config.typesOfMQE || []);
+
   if (props.needQuery) {
     queryInstance();
   }
@@ -169,36 +165,7 @@ limitations under the License. -->
         attributes: d.attributes,
       };
     });
-    if (props.config.metricMode === MetricModes.Expression) {
-      queryInstanceExpressions(currentInstances);
-      return;
-    }
-    const metrics = props.config.metrics || [];
-    const types = props.config.metricTypes || [];
-
-    if (metrics.length && metrics[0] && types.length && types[0]) {
-      const params = await useQueryPodsMetrics(currentInstances, props.config, 
EntityType[3].value);
-      const json = await dashboardStore.fetchMetricValue(params);
-
-      if (json.errors) {
-        ElMessage.error(json.errors);
-        return;
-      }
-      const { data, names, metricConfigArr, metricTypesArr } = 
usePodsSource(currentInstances, json, {
-        ...props.config,
-        metricConfig: metricConfig.value,
-      });
-      instances.value = data;
-      colMetrics.value = names;
-      metricTypes.value = metricTypesArr;
-      metricConfig.value = metricConfigArr;
-
-      return;
-    }
-    instances.value = currentInstances;
-    colMetrics.value = [];
-    metricTypes.value = [];
-    metricConfig.value = [];
+    queryInstanceExpressions(currentInstances);
   }
 
   async function queryInstanceExpressions(currentInstances: Instance[]) {
@@ -214,7 +181,7 @@ limitations under the License. -->
       instances.value = params.data;
       colMetrics.value = params.names;
       colSubMetrics.value = params.subNames;
-      metricTypes.value = params.metricTypesArr;
+      typesOfMQE.value = params.metricTypesArr;
       metricConfig.value = params.metricConfigArr;
       emit("expressionTips", { tips: params.expressionsTips, subTips: 
params.subExpressionsTips });
 
@@ -223,7 +190,7 @@ limitations under the License. -->
     instances.value = currentInstances;
     colSubMetrics.value = [];
     colMetrics.value = [];
-    metricTypes.value = [];
+    typesOfMQE.value = [];
     metricConfig.value = [];
     emit("expressionTips", [], []);
   }
@@ -262,19 +229,15 @@ limitations under the License. -->
 
   watch(
     () => [
-      ...(props.config.metricTypes || []),
-      ...(props.config.metrics || []),
       ...(props.config.metricConfig || []),
       ...(props.config.expressions || []),
       ...(props.config.subExpressions || []),
-      props.config.metricMode,
     ],
     (data, old) => {
       if (JSON.stringify(data) === JSON.stringify(old)) {
         return;
       }
       metricConfig.value = props.config.metricConfig;
-      metricMode.value = props.config.metricMode;
       queryInstanceMetrics(instances.value);
     },
   );
diff --git a/src/views/dashboard/graphs/ServiceList.vue 
b/src/views/dashboard/graphs/ServiceList.vue
index 1cf8f641..7a3a8bdd 100644
--- a/src/views/dashboard/graphs/ServiceList.vue
+++ b/src/views/dashboard/graphs/ServiceList.vue
@@ -51,8 +51,7 @@ limitations under the License. -->
           :config="{
             ...config,
             metricConfig,
-            metricTypes,
-            metricMode,
+            typesOfMQE,
           }"
           v-if="colMetrics.length"
         />
@@ -78,9 +77,8 @@ limitations under the License. -->
   import { useDashboardStore } from "@/store/modules/dashboard";
   import { useAppStoreWithOut } from "@/store/modules/app";
   import type { Service } from "@/types/selector";
-  import { useQueryPodsMetrics, usePodsSource } from 
"@/hooks/useMetricsProcessor";
   import { useExpressionsQueryPodsMetrics } from 
"@/hooks/useExpressionsProcessor";
-  import { EntityType, MetricModes } from "../data";
+  import { EntityType } from "../data";
   import router from "@/router";
   import getDashboard from "@/hooks/useDashboardsSession";
   import type { MetricConfigOpt } from "@/types/dashboard";
@@ -95,12 +93,9 @@ limitations under the License. -->
       type: Object as PropType<
         ServiceListConfig & {
           i: string;
-          metrics: string[];
-          metricTypes: string[];
           isEdit: boolean;
           names: string[];
           metricConfig: MetricConfigOpt[];
-          metricMode: string;
           expressions: string[];
           typesOfMQE: string[];
           subExpressions: string[];
@@ -125,8 +120,7 @@ limitations under the License. -->
   const groups = ref<any>({});
   const sortServices = ref<(Service & { merge: boolean })[]>([]);
   const metricConfig = ref<MetricConfigOpt[]>(props.config.metricConfig || []);
-  const metricTypes = ref<string[]>(props.config.metricTypes || []);
-  const metricMode = ref<string>(props.config.metricMode);
+  const typesOfMQE = ref<string[]>(props.config.typesOfMQE || []);
 
   queryServices();
 
@@ -211,43 +205,7 @@ limitations under the License. -->
         shortName: d.shortName,
       };
     });
-    if (props.config.metricMode === MetricModes.Expression) {
-      queryServiceExpressions(currentServices);
-      return;
-    }
-    const metrics = props.config.metrics || [];
-    const types = props.config.metricTypes || [];
-
-    if (metrics.length && metrics[0] && types.length && types[0]) {
-      const params = await useQueryPodsMetrics(
-        currentServices,
-        { ...props.config, metricConfig: metricConfig.value || [] },
-        EntityType[0].value,
-      );
-      const json = await dashboardStore.fetchMetricValue(params);
-
-      if (json.errors) {
-        ElMessage.error(json.errors);
-        return;
-      }
-
-      const { data, names, metricConfigArr, metricTypesArr } = 
usePodsSource(currentServices, json, {
-        ...props.config,
-        metricConfig: metricConfig.value || [],
-      });
-
-      services.value = data;
-      colMetrics.value = names;
-      metricTypes.value = metricTypesArr;
-      metricConfig.value = metricConfigArr;
-
-      return;
-    }
-    services.value = currentServices;
-    colMetrics.value = [];
-    colMetrics.value = [];
-    metricTypes.value = [];
-    metricConfig.value = [];
+    queryServiceExpressions(currentServices);
   }
   async function queryServiceExpressions(currentServices: Service[]) {
     const expressions = props.config.expressions || [];
@@ -262,16 +220,16 @@ limitations under the License. -->
       services.value = params.data;
       colMetrics.value = params.names;
       colSubMetrics.value = params.subNames;
-      metricTypes.value = params.metricTypesArr;
       metricConfig.value = params.metricConfigArr;
+      typesOfMQE.value = params.metricTypesArr;
       emit("expressionTips", { tips: params.expressionsTips, subTips: 
params.subExpressionsTips });
       return;
     }
     services.value = currentServices;
     colMetrics.value = [];
     colSubMetrics.value = [];
-    metricTypes.value = [];
     metricConfig.value = [];
+    typesOfMQE.value = [];
     emit("expressionTips", [], []);
   }
   function objectSpanMethod(param: any): any {
@@ -306,19 +264,15 @@ limitations under the License. -->
 
   watch(
     () => [
-      ...(props.config.metricTypes || []),
-      ...(props.config.metrics || []),
       ...(props.config.metricConfig || []),
       ...(props.config.expressions || []),
       ...(props.config.subExpressions || []),
-      props.config.metricMode,
     ],
     (data, old) => {
       if (JSON.stringify(data) === JSON.stringify(old)) {
         return;
       }
       metricConfig.value = props.config.metricConfig;
-      metricMode.value = props.config.metricMode;
       queryServiceMetrics(services.value);
     },
   );
diff --git a/src/views/dashboard/graphs/Table.vue 
b/src/views/dashboard/graphs/Table.vue
index 2ab46c05..baaf2190 100644
--- a/src/views/dashboard/graphs/Table.vue
+++ b/src/views/dashboard/graphs/Table.vue
@@ -56,7 +56,6 @@ limitations under the License. -->
       type: Object as PropType<{
         showTableValues: boolean;
         tableHeaderCol2: string;
-        metricTypes: string[];
         typesOfMQE: string[];
       }>,
       default: () => ({ showTableValues: true }),
@@ -66,10 +65,6 @@ limitations under the License. -->
   const { t } = useI18n();
   const nameWidth = computed(() => (props.config.showTableValues ? 80 : 100));
   const dataKeys = computed(() => {
-    if (props.config.metricTypes && props.config.metricTypes[0] === 
"readMetricsValue") {
-      const keys = Object.keys(props.data || {});
-      return keys;
-    }
     const keys = Object.keys(props.data || {}).filter(
       (i: string) => Array.isArray(props.data[i]) && props.data[i].length,
     );
diff --git a/src/views/dashboard/graphs/TopList.vue 
b/src/views/dashboard/graphs/TopList.vue
index 434a18ae..1b5b427d 100644
--- a/src/views/dashboard/graphs/TopList.vue
+++ b/src/views/dashboard/graphs/TopList.vue
@@ -64,8 +64,7 @@ limitations under the License. -->
   import copy from "@/utils/copy";
   import { TextColors } from "@/views/dashboard/data";
   import Trace from "@/views/dashboard/related/trace/Index.vue";
-  import { QueryOrders, Status, RefIdTypes, ProtocolTypes, 
ExpressionResultType } from "../data";
-  import { WidgetType } from "@/views/dashboard/data";
+  import { WidgetType, QueryOrders, Status, RefIdTypes, ExpressionResultType } 
from "@/views/dashboard/data";
 
   /*global defineProps */
   const props = defineProps({
@@ -77,10 +76,8 @@ limitations under the License. -->
     },
     config: {
       type: Object as PropType<{
-        metricMode: string;
         color: string;
-        metrics: string[];
-        metricTypes: string[];
+        expressions: string[];
         typesOfMQE: string[];
         relatedTrace: any;
       }>,
@@ -116,11 +113,8 @@ limitations under the License. -->
       queryOrder: QueryOrders[1].value,
       status: Status[2].value,
       id: item.refId,
-      metricValue: [{ label: props.config.metrics[0], data: item.value, value: 
item.name }],
-      isReadRecords:
-        props.config.typesOfMQE.includes(ExpressionResultType.RECORD_LIST) ||
-        props.config.metricTypes.includes(ProtocolTypes.ReadRecords) ||
-        undefined,
+      metricValue: [{ label: props.config.expressions[0], data: item.value, 
value: item.name }],
+      isReadRecords: 
props.config.typesOfMQE.includes(ExpressionResultType.RECORD_LIST) || undefined,
     };
     traceOptions.value = {
       ...traceOptions.value,
diff --git a/src/views/dashboard/graphs/components/ColumnGraph.vue 
b/src/views/dashboard/graphs/components/ColumnGraph.vue
index 0e57216e..22be8438 100644
--- a/src/views/dashboard/graphs/components/ColumnGraph.vue
+++ b/src/views/dashboard/graphs/components/ColumnGraph.vue
@@ -22,23 +22,7 @@ limitations under the License. -->
   >
     <template #default="scope">
       <div class="chart">
-        <Line
-          v-if="useListConfig(config, index).isLinear && config.metricMode !== 
MetricModes.Expression"
-          :data="{
-            [metric]: scope.row[metric] && scope.row[metric].values,
-          }"
-          :intervalTime="intervalTime"
-          :config="{
-            showXAxis: false,
-            showYAxis: false,
-            smallTips: true,
-            showlabels: false,
-          }"
-        />
-        <span
-          class="item flex-h"
-          v-else-if="useListConfig(config, index).isAvg || config.metricMode 
=== MetricModes.Expression"
-        >
+        <span class="item flex-h">
           <el-popover placement="left" :width="400" trigger="click">
             <template #reference>
               <span class="trend">
@@ -70,7 +54,6 @@ limitations under the License. -->
             />
           </span>
         </span>
-        <Card v-else :data="{ [metric]: scope.row[metric] }" :config="{ 
textAlign: 'left' }" />
       </div>
     </template>
   </el-table-column>
@@ -79,11 +62,9 @@ limitations under the License. -->
 <script lang="ts" setup>
   import type { PropType } from "vue";
   import type { MetricConfigOpt } from "@/types/dashboard";
-  import { useListConfig } from "@/hooks/useListConfig";
   import Line from "../Line.vue";
   import Card from "../Card.vue";
-  import { MetricQueryTypes } from "@/hooks/data";
-  import { ExpressionResultType, MetricModes } from "@/views/dashboard/data";
+  import { ExpressionResultType } from "@/views/dashboard/data";
 
   /*global defineProps */
   const props = defineProps({
@@ -92,9 +73,8 @@ limitations under the License. -->
     config: {
       type: Object as PropType<{
         i: string;
-        metricTypes: string[];
+        typesOfMQE: string[];
         metricConfig: MetricConfigOpt[];
-        metricMode: string;
       }>,
       default: () => ({}),
     },
@@ -120,13 +100,9 @@ limitations under the License. -->
     }
     if (label) {
       if (
-        (
-          [
-            MetricQueryTypes.ReadLabeledMetricsValues,
-            ExpressionResultType.TIME_SERIES_VALUES,
-            ExpressionResultType.SINGLE_VALUE,
-          ] as string[]
-        ).includes(props.config.metricTypes[i])
+        ([ExpressionResultType.TIME_SERIES_VALUES, 
ExpressionResultType.SINGLE_VALUE] as string[]).includes(
+          props.config.typesOfMQE[i],
+        )
       ) {
         const name = (label || "").split(",").map((item: string) => 
item.replace(/^\s*|\s*$/g, ""))[
           props.config.metricConfig[i].index || 0
diff --git a/src/views/dashboard/related/topology/config/Metrics.vue 
b/src/views/dashboard/related/topology/config/Metrics.vue
index 6a5d6f7f..d33b759c 100644
--- a/src/views/dashboard/related/topology/config/Metrics.vue
+++ b/src/views/dashboard/related/topology/config/Metrics.vue
@@ -19,7 +19,7 @@ limitations under the License. -->
         {{ t("expressions") }}
       </span>
       <span class="label" v-else>
-        {{ t(dashboardStore.selectedGrid.metricMode === MetricModes.General ? 
"metrics" : "expressions") }}
+        {{ t("expressions") }}
       </span>
       <SelectSingle :value="currentMetric" :options="metricList" 
@change="changeMetric" class="selectors" />
     </div>
@@ -43,33 +43,19 @@ limitations under the License. -->
         @change="changeConfigs({ label: currentConfig.label })"
       />
     </div>
-    <div
-      class="item mb-10"
-      v-if="type !== 'hierarchyServicesConfig' && 
dashboardStore.selectedGrid.metricMode === MetricModes.General"
-    >
-      <span class="label">{{ t("aggregation") }}</span>
-      <SelectSingle
-        :value="currentConfig.calculation"
-        :options="CalculationOpts"
-        @change="changeConfigs({ calculation: $event })"
-        class="selectors"
-        :clearable="true"
-      />
-    </div>
   </div>
 </template>
 <script lang="ts" setup>
   import { ref, computed, watch } from "vue";
   import { useI18n } from "vue-i18n";
   import type { Option } from "@/types/app";
-  import { CalculationOpts, MetricModes, EntityType, ConfigFieldTypes } from 
"@/views/dashboard/data";
+  import { EntityType, ConfigFieldTypes } from "@/views/dashboard/data";
   import { useDashboardStore } from "@/store/modules/dashboard";
   import getDashboard from "@/hooks/useDashboardsSession";
 
   /*global defineEmits, defineProps */
   const props = defineProps({
     type: { type: String, default: "" },
-    isExpression: { type: Boolean, default: true },
     layer: { type: String, default: "" },
     expressions: { type: Array<string>, default: () => [] },
     entity: { type: String, default: EntityType[0].value },
@@ -82,23 +68,16 @@ limitations under the License. -->
       return props.expressions || [];
     }
     let metrics: string[] = [];
-    const {
-      linkServerExpressions,
-      linkServerMetrics,
-      linkClientExpressions,
-      linkClientMetrics,
-      nodeExpressions,
-      nodeMetrics,
-    } = dashboardStore.selectedGrid;
+    const { linkServerExpressions, linkClientExpressions, nodeExpressions } = 
dashboardStore.selectedGrid;
     switch (props.type) {
       case "linkServerMetricConfig":
-        metrics = props.isExpression ? linkServerExpressions : 
linkServerMetrics;
+        metrics = linkServerExpressions;
         break;
       case "linkClientMetricConfig":
-        metrics = props.isExpression ? linkClientExpressions : 
linkClientMetrics;
+        metrics = linkClientExpressions;
         break;
       case "nodeMetricConfig":
-        metrics = props.isExpression ? nodeExpressions : nodeMetrics;
+        metrics = nodeExpressions;
         break;
     }
     return metrics || [];
diff --git a/src/views/dashboard/related/topology/config/Settings.vue 
b/src/views/dashboard/related/topology/config/Settings.vue
index 45af09ce..1d231a9f 100644
--- a/src/views/dashboard/related/topology/config/Settings.vue
+++ b/src/views/dashboard/related/topology/config/Settings.vue
@@ -13,17 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 
or implied.
 See the License for the specific language governing permissions and
 limitations under the License. -->
 <template>
-  <div class="mt-20">
-    <h5 class="title">{{ t("metricMode") }}</h5>
-    <el-switch
-      v-model="isExpression"
-      class="mt-5"
-      active-text="Expressions"
-      inactive-text="General"
-      size="small"
-      @change="changeMetricMode"
-    />
-  </div>
   <div class="mb-20">
     <h5 class="title">{{ t("callSettings") }}</h5>
     <div class="label">{{ t("linkDashboard") }}</div>
@@ -38,21 +27,16 @@ limitations under the License. -->
     />
     <div class="label">
       <span>{{ t("linkServerMetrics") }}</span>
-      <el-popover
-        placement="left"
-        :width="400"
-        trigger="click"
-        v-if="isExpression ? states.linkServerExpressions.length : 
states.linkServerMetrics.length"
-      >
+      <el-popover placement="left" :width="400" trigger="click" 
v-if="states.linkServerExpressions.length">
         <template #reference>
           <span @click="setConfigType('linkServerMetricConfig')">
             <Icon class="cp ml-5" iconName="mode_edit" size="middle" />
           </span>
         </template>
-        <Metrics :type="configType" :isExpression="isExpression" 
@update="updateSettings" />
+        <Metrics :type="configType" @update="updateSettings" />
       </el-popover>
     </div>
-    <div v-if="isExpression">
+    <div>
       <Tags
         :tags="states.linkServerExpressions"
         :vertical="true"
@@ -60,34 +44,19 @@ limitations under the License. -->
         @change="(param: string[]) => changeLinkServerExpressions(param)"
       />
     </div>
-    <Selector
-      v-else
-      class="inputs"
-      :multiple="true"
-      :value="states.linkServerMetrics"
-      :options="states.linkMetricList"
-      size="small"
-      placeholder="Select metrics"
-      @change="updateLinkServerMetrics"
-    />
     <span v-show="dashboardStore.entity !== EntityType[2].value">
       <div class="label">
         <span>{{ t("linkClientMetrics") }}</span>
-        <el-popover
-          placement="left"
-          :width="400"
-          trigger="click"
-          v-if="isExpression ? states.linkClientExpressions.length : 
states.linkClientMetrics.length"
-        >
+        <el-popover placement="left" :width="400" trigger="click" 
v-if="states.linkClientExpressions.length">
           <template #reference>
             <span @click="setConfigType('linkClientMetricConfig')">
               <Icon class="cp ml-5" iconName="mode_edit" size="middle" />
             </span>
           </template>
-          <Metrics :type="configType" :isExpression="isExpression" 
@update="updateSettings" />
+          <Metrics :type="configType" @update="updateSettings" />
         </el-popover>
       </div>
-      <div v-if="isExpression">
+      <div>
         <Tags
           :tags="states.linkClientExpressions"
           :vertical="true"
@@ -95,16 +64,6 @@ limitations under the License. -->
           @change="(param: string[]) => changeLinkClientExpressions(param)"
         />
       </div>
-      <Selector
-        v-else
-        class="inputs"
-        :multiple="true"
-        :value="states.linkClientMetrics"
-        :options="states.linkMetricList"
-        size="small"
-        placeholder="Select metrics"
-        @change="updateLinkClientMetrics"
-      />
     </span>
   </div>
   <div>
@@ -149,21 +108,16 @@ limitations under the License. -->
     </div>
     <div class="label">
       <span>{{ t("nodeMetrics") }}</span>
-      <el-popover
-        placement="left"
-        :width="400"
-        trigger="click"
-        v-if="isExpression ? states.nodeExpressions.length : 
states.nodeMetrics.length"
-      >
+      <el-popover placement="left" :width="400" trigger="click" 
v-if="states.nodeExpressions.length">
         <template #reference>
           <span @click="setConfigType('nodeMetricConfig')">
             <Icon class="cp ml-5" iconName="mode_edit" size="middle" />
           </span>
         </template>
-        <Metrics :type="configType" :isExpression="isExpression" 
@update="updateSettings" />
+        <Metrics :type="configType" @update="updateSettings" />
       </el-popover>
     </div>
-    <div v-if="isExpression">
+    <div>
       <Tags
         :tags="states.nodeExpressions"
         :vertical="true"
@@ -171,28 +125,17 @@ limitations under the License. -->
         @change="(param: string[]) => changeNodeExpressions(param)"
       />
     </div>
-    <Selector
-      v-else
-      class="inputs"
-      :multiple="true"
-      :value="states.nodeMetrics"
-      :options="states.nodeMetricList"
-      size="small"
-      placeholder="Select metrics"
-      @change="updateNodeMetrics"
-    />
   </div>
   <div v-show="isService">
     <h5 class="title">{{ t("legendSettings") }}</h5>
-    <span v-if="isExpression">
+    <span>
       <div class="label">Healthy Description</div>
       <el-input v-model="description.healthy" placeholder="Please input 
description" size="small" class="mt-5" />
     </span>
     <div class="label">
-      <span>{{ t(isExpression ? "unhealthyExpression" : "conditions") }}</span>
+      <span>{{ t("unhealthyExpression") }}</span>
       <el-tooltip
         class="cp"
-        v-if="isExpression"
         content="The node would be red to indicate unhealthy status when the 
expression return greater than 0"
       >
         <span>
@@ -200,50 +143,9 @@ limitations under the License. -->
         </span>
       </el-tooltip>
     </div>
-    <div v-if="isExpression">
+    <div>
       <el-input v-model="legendMQE.expression" placeholder="Please input a 
expression" size="small" class="inputs" />
     </div>
-    <div v-for="(metric, index) of legend" :key="index" v-else>
-      <Selector
-        class="item"
-        :value="metric.name"
-        :options="states.nodeMetricList"
-        size="small"
-        placeholder="Select a metric"
-        @change="changeLegend(LegendOpt.NAME, $event, index)"
-      />
-      <Selector
-        class="input-small"
-        :value="metric.condition"
-        :options="MetricConditions"
-        size="small"
-        placeholder="Select a condition"
-        @change="changeLegend(LegendOpt.CONDITION, $event, index)"
-      />
-      <el-input
-        v-model="metric.value"
-        placeholder="Please input a value"
-        type="number"
-        @change="changeLegend(LegendOpt.VALUE, $event, index)"
-        size="small"
-        class="item"
-      />
-      <span>
-        <Icon class="cp delete" iconName="remove_circle_outline" size="middle" 
@click="deleteMetric(index)" />
-        <Icon
-          class="cp"
-          iconName="add_circle_outlinecontrol_point"
-          size="middle"
-          v-show="index === legend.length - 1 && legend.length < 5"
-          @click="addMetric"
-        />
-      </span>
-      <div v-show="index !== legend.length - 1">&&</div>
-    </div>
-    <span v-if="!isExpression">
-      <div class="label">Healthy Description</div>
-      <el-input v-model="description.healthy" placeholder="Please input 
description" size="small" class="mt-5" />
-    </span>
     <div class="label">Unhealthy Description</div>
     <el-input v-model="description.unhealthy" placeholder="Please input 
description" size="small" class="mt-5" />
     <el-button @click="setLegend" class="mt-20" size="small" type="primary">
@@ -257,20 +159,9 @@ limitations under the License. -->
   import { useDashboardStore } from "@/store/modules/dashboard";
   import { useTopologyStore } from "@/store/modules/topology";
   import { ElMessage } from "element-plus";
-  import {
-    MetricCatalog,
-    ScopeType,
-    MetricConditions,
-    EntityType,
-    LegendOpt,
-    MetricsType,
-    MetricModes,
-    CallTypes,
-  } from "@/views/dashboard/data";
+  import { ScopeType, EntityType, CallTypes } from "@/views/dashboard/data";
   import type { Option } from "@/types/app";
-  import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
   import { useQueryTopologyExpressionsProcessor } from 
"@/hooks/useExpressionsProcessor";
-  import type { Node } from "@/types/topology";
   import type { DashboardItem, MetricConfigOpt } from "@/types/dashboard";
   import Metrics from "./Metrics.vue";
 
@@ -280,7 +171,6 @@ limitations under the License. -->
   const dashboardStore = useDashboardStore();
   const topologyStore = useTopologyStore();
   const { selectedGrid } = dashboardStore;
-  const isExpression = ref<boolean>(dashboardStore.selectedGrid.metricMode === 
MetricModes.Expression);
   const nodeDashboard =
     selectedGrid.nodeDashboard && selectedGrid.nodeDashboard.length ? 
selectedGrid.nodeDashboard : "";
   const isService = [EntityType[0].value, 
EntityType[1].value].includes(dashboardStore.entity);
@@ -296,11 +186,6 @@ limitations under the License. -->
       scope: string;
       dashboard: string;
     }[];
-    linkServerMetrics: string[];
-    linkClientMetrics: string[];
-    nodeMetrics: string[];
-    nodeMetricList: Option[];
-    linkMetricList: Option[];
     linkDashboards: (DashboardItem & { label: string; value: string })[];
     nodeDashboards: (DashboardItem & { label: string; value: string })[];
     linkServerExpressions: string[];
@@ -309,27 +194,18 @@ limitations under the License. -->
   }>({
     linkDashboard: selectedGrid.linkDashboard || "",
     nodeDashboard: selectedGrid.nodeDashboard || [],
-    linkServerMetrics: selectedGrid.linkServerMetrics || [],
-    linkClientMetrics: selectedGrid.linkClientMetrics || [],
-    nodeMetrics: selectedGrid.nodeMetrics || [],
-    nodeMetricList: [],
-    linkMetricList: [],
     linkDashboards: [],
     nodeDashboards: [],
     linkServerExpressions: selectedGrid.linkServerExpressions || [],
     linkClientExpressions: selectedGrid.linkClientExpressions || [],
     nodeExpressions: selectedGrid.nodeExpressions || [],
   });
-  const l = selectedGrid.legend && selectedGrid.legend.length;
-  const legend = ref<{ name: string; condition: string; value: string }[]>(
-    l ? selectedGrid.legend : [{ name: "", condition: "", value: "" }],
-  );
   const legendMQE = ref<{ expression: string }>(selectedGrid.legendMQE || { 
expression: "" });
   const configType = ref<string>("");
   const description = reactive<any>(selectedGrid.description || {});
 
-  getMetricList();
-  async function getMetricList() {
+  getDashboardList();
+  async function getDashboardList() {
     const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
     const json = await dashboardStore.fetchMetricList();
     if (json.errors) {
@@ -351,13 +227,6 @@ limitations under the License. -->
       },
       [],
     );
-    states.nodeMetricList = (json.data.metrics || []).filter(
-      (d: { type: string }) => d.type === MetricsType.REGULAR_VALUE,
-    );
-    states.linkMetricList = (json.data.metrics || []).filter(
-      (d: { catalog: string; type: string }) =>
-        entity + "Relation" === (MetricCatalog as any)[d.catalog] && d.type 
=== MetricsType.REGULAR_VALUE,
-    );
     if (isService) {
       return;
     }
@@ -373,36 +242,15 @@ limitations under the License. -->
   }
   async function setLegend() {
     updateSettings();
-    if (isExpression.value) {
-      const expression = dashboardStore.selectedGrid.legendMQE && 
dashboardStore.selectedGrid.legendMQE.expression;
-      if (!expression) {
-        emit("updateNodes");
-        return;
-      }
-      const { getExpressionQuery } = 
useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes);
-      const param = getExpressionQuery();
-      const res = await topologyStore.getNodeExpressionValue(param);
-      if (res.errors) {
-        ElMessage.error(res.errors);
-      } else {
-        topologyStore.setLegendValues([expression], res.data);
-      }
+    const expression = dashboardStore.selectedGrid.legendMQE && 
dashboardStore.selectedGrid.legendMQE.expression;
+    const { getExpressionQuery } = 
useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes);
+    const param = getExpressionQuery();
+    const res = await topologyStore.getNodeExpressionValue(param);
+    if (res.errors) {
+      ElMessage.error(res.errors);
     } else {
-      const names = dashboardStore.selectedGrid.legend.map((d: any) => d.name 
&& d.condition && d.value);
-      if (!names.length) {
-        emit("updateNodes");
-        return;
-      }
-      const ids = topologyStore.nodes.map((d: Node) => d.id);
-      const param = await useQueryTopologyMetrics(names, ids);
-      const res = await topologyStore.getLegendMetrics(param);
-
-      if (res.errors) {
-        ElMessage.error(res.errors);
-      }
+      topologyStore.setLegendValues([expression], res.data);
     }
-
-    emit("updateNodes");
   }
   function changeNodeDashboard(opt: any) {
     states.nodeDashboard = opt[0].value;
@@ -412,9 +260,6 @@ limitations under the License. -->
     states.linkDashboard = opt[0].value;
     updateSettings();
   }
-  function changeLegend(type: string, opt: any, index: number) {
-    (legend.value[index] as any)[type] = opt[0].value || opt;
-  }
   function changeScope(index: number, opt: Option[] | any) {
     items[index].scope = opt[0].value;
     const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
@@ -445,27 +290,15 @@ limitations under the License. -->
     updateSettings();
   }
   function updateSettings(metricConfig?: { [key: string]: MetricConfigOpt[] }) 
{
-    let metrics = [];
-    if (isExpression.value) {
-      metrics = legend.value.filter((d: any) => d.name);
-    } else {
-      metrics = legend.value.filter((d: any) => d.name && d.value && 
d.condition);
-    }
-
     const param = {
       ...dashboardStore.selectedGrid,
       linkDashboard: states.linkDashboard,
       nodeDashboard: isService
         ? items.filter((d: { scope: string; dashboard: string }) => 
d.dashboard)
         : states.nodeDashboard,
-      linkServerMetrics: states.linkServerMetrics,
-      linkClientMetrics: states.linkClientMetrics,
-      nodeMetrics: states.nodeMetrics,
       linkServerExpressions: states.linkServerExpressions,
       linkClientExpressions: states.linkClientExpressions,
       nodeExpressions: states.nodeExpressions,
-      metricMode: isExpression.value ? MetricModes.Expression : 
MetricModes.General,
-      legend: metrics,
       legendMQE: legendMQE.value,
       ...metricConfig,
       description,
@@ -474,30 +307,8 @@ limitations under the License. -->
     dashboardStore.setConfigs(param);
     emit("update", param);
   }
-  function updateLinkServerMetrics(options: Option[] | any) {
-    const opt = options.map((d: Option) => d.value);
-    const index = states.linkServerMetrics.findIndex((d: any) => 
!opt.includes(d));
-    states.linkServerMetrics = opt;
-    if (index < 0) {
-      changeLinkServerMetrics();
-      return;
-    }
-    const origin = dashboardStore.selectedGrid.linkServerMetricConfig || [];
-    const config = origin.length === 1 ? [] : origin.splice(index, 1);
-    changeLinkServerMetrics({ linkServerMetricConfig: config });
-  }
-  async function changeLinkServerMetrics(config?: { [key: string]: 
MetricConfigOpt[] }) {
-    updateSettings(config);
-    if (!states.linkServerMetrics.length) {
-      topologyStore.setLinkServerMetrics({});
-      return;
-    }
-    topologyStore.getLinkServerMetrics(states.linkServerMetrics);
-  }
+
   function changeLinkServerExpressions(param: string[]) {
-    if (!isExpression.value) {
-      return;
-    }
     states.linkServerExpressions = param;
     updateSettings();
     if (!states.linkServerExpressions.length) {
@@ -507,9 +318,6 @@ limitations under the License. -->
     topologyStore.getLinkExpressions(states.linkServerExpressions, 
CallTypes.Server);
   }
   function changeLinkClientExpressions(param: string[]) {
-    if (!isExpression.value) {
-      return;
-    }
     states.linkClientExpressions = param;
     updateSettings();
     if (!states.linkClientExpressions.length) {
@@ -518,63 +326,11 @@ limitations under the License. -->
     }
     topologyStore.getLinkExpressions(states.linkClientExpressions, 
CallTypes.Client);
   }
-  function updateLinkClientMetrics(options: Option[] | any) {
-    const opt = options.map((d: Option) => d.value);
-    const index = states.linkClientMetrics.findIndex((d: any) => 
!opt.includes(d));
-    states.linkClientMetrics = opt;
-    if (index < 0) {
-      changeLinkClientMetrics();
-      return;
-    }
-    const origin = dashboardStore.selectedGrid.linkClientMetricConfig || [];
-    const config = origin.length === 1 ? [] : origin.splice(index, 1);
-    changeLinkClientMetrics({ linkClientMetricConfig: config });
-  }
-  async function changeLinkClientMetrics(config?: { [key: string]: 
MetricConfigOpt[] }) {
-    updateSettings(config);
-    if (!states.linkClientMetrics.length) {
-      topologyStore.setLinkClientMetrics({});
-      return;
-    }
-    topologyStore.getLinkClientMetrics(states.linkClientMetrics);
-  }
-  function updateNodeMetrics(options: Option[] | any) {
-    const opt = options.map((d: Option) => d.value);
-    const index = states.nodeMetrics.findIndex((d: any) => !opt.includes(d));
-    states.nodeMetrics = opt;
-    if (index < 0) {
-      changeNodeMetrics();
-      return;
-    }
-    const origin = dashboardStore.selectedGrid.nodeMetricConfig || [];
-    const config = origin.length === 1 ? [] : origin.splice(index, 1);
-    changeNodeMetrics({ nodeMetricConfig: config });
-  }
-  async function changeNodeMetrics(config?: { [key: string]: MetricConfigOpt[] 
}) {
-    updateSettings(config);
-    if (!states.nodeMetrics.length) {
-      topologyStore.setNodeMetricValue({});
-      return;
-    }
-    topologyStore.queryNodeMetrics(states.nodeMetrics);
-  }
-  function deleteMetric(index: number) {
-    if (legend.value.length === 1) {
-      legend.value = [{ name: "", condition: "", value: "" }];
-      return;
-    }
-    legend.value.splice(index, 1);
-  }
-  function addMetric() {
-    legend.value.push({ name: "", condition: "", value: "" });
-  }
+
   function setConfigType(type: string) {
     configType.value = type;
   }
   function changeNodeExpressions(param: string[]) {
-    if (!isExpression.value) {
-      return;
-    }
     states.nodeExpressions = param;
     updateSettings();
     if (!states.nodeExpressions.length) {
@@ -583,25 +339,6 @@ limitations under the License. -->
     }
     topologyStore.queryNodeExpressions(states.nodeExpressions);
   }
-  function changeMetricMode() {
-    legend.value = [{ name: "", condition: "", value: "" }];
-    const config = {
-      linkServerMetricConfig: [],
-      linkClientMetricConfig: [],
-      nodeMetricConfig: [],
-    };
-    if (isExpression.value) {
-      states.linkServerMetrics = [];
-      states.linkClientMetrics = [];
-      states.nodeMetrics = [];
-    } else {
-      states.linkServerExpressions = [];
-      states.linkClientExpressions = [];
-      states.nodeExpressions = [];
-    }
-
-    updateSettings(config);
-  }
 </script>
 <style lang="scss" scoped>
   .inputs {
diff --git a/src/views/dashboard/related/topology/pod/InstanceMap.vue 
b/src/views/dashboard/related/topology/pod/InstanceMap.vue
index f0b12857..9e389d86 100644
--- a/src/views/dashboard/related/topology/pod/InstanceMap.vue
+++ b/src/views/dashboard/related/topology/pod/InstanceMap.vue
@@ -41,7 +41,6 @@ limitations under the License. -->
   import router from "@/router";
   import { ElMessage } from "element-plus";
   import type { MetricConfigOpt } from "@/types/dashboard";
-  import { aggregation } from "@/hooks/useMetricsProcessor";
   import getDashboard from "@/hooks/useDashboardsSession";
   import Graph from "../components/Graph.vue";
 
@@ -129,8 +128,8 @@ limitations under the License. -->
           (val: { id: string; value: unknown }) => val.id === data.id,
         ) || {};
       const opt: MetricConfigOpt = nodeMetricConfig[index] || {};
-      const v = aggregation(metric.value, opt);
-      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${v} ${opt.unit || ""}</div>`;
+
+      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${metric.value} ${opt.unit || ""}</div>`;
     });
     const tipHtml = [
       `<div class="mb-5"><span class="grey">name: 
</span>${data.name}</div><div class="mb-5"><span class="grey">layer: 
</span>${data.layer}</div>`,
diff --git a/src/views/dashboard/related/topology/pod/PodMap.vue 
b/src/views/dashboard/related/topology/pod/PodMap.vue
index 30e61037..92c4fa1f 100644
--- a/src/views/dashboard/related/topology/pod/PodMap.vue
+++ b/src/views/dashboard/related/topology/pod/PodMap.vue
@@ -69,7 +69,7 @@ limitations under the License. -->
   import { useDashboardStore } from "@/store/modules/dashboard";
   import { useSelectorStore } from "@/store/modules/selectors";
   import { useAppStoreWithOut } from "@/store/modules/app";
-  import { EntityType, DepthList, MetricModes, CallTypes } from 
"@/views/dashboard/data";
+  import { EntityType, DepthList, CallTypes } from "@/views/dashboard/data";
   import { ElMessage } from "element-plus";
   import Sankey from "./Sankey.vue";
   import Settings from "../config/Settings.vue";
@@ -119,15 +119,9 @@ limitations under the License. -->
     };
     height.value = dom.height - 70;
     width.value = dom.width - 5;
-    if (settings.value.metricMode === MetricModes.Expression) {
-      topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
-      topologyStore.getLinkExpressions(settings.value.linkClientExpressions || 
[], CallTypes.Client);
-      topologyStore.getLinkExpressions(settings.value.linkServerExpressions || 
[], CallTypes.Server);
-    } else {
-      topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || 
[]);
-      topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || 
[]);
-      topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []);
-    }
+    topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
+    topologyStore.getLinkExpressions(settings.value.linkClientExpressions || 
[], CallTypes.Client);
+    topologyStore.getLinkExpressions(settings.value.linkServerExpressions || 
[], CallTypes.Server);
   }
 
   function resize() {
diff --git a/src/views/dashboard/related/topology/pod/Sankey.vue 
b/src/views/dashboard/related/topology/pod/Sankey.vue
index 231b366f..5b45e0b6 100644
--- a/src/views/dashboard/related/topology/pod/Sankey.vue
+++ b/src/views/dashboard/related/topology/pod/Sankey.vue
@@ -22,8 +22,6 @@ limitations under the License. -->
   import { useTopologyStore } from "@/store/modules/topology";
   import type { Node, Call } from "@/types/topology";
   import type { MetricConfigOpt } from "@/types/dashboard";
-  import { aggregation } from "@/hooks/useMetricsProcessor";
-  import { MetricModes } from "@/views/dashboard/data";
   import { useAppStoreWithOut } from "@/store/modules/app";
   import { Themes } from "@/constants/data";
 
@@ -85,14 +83,8 @@ limitations under the License. -->
     };
   }
   function linkTooltip(data: Call) {
-    const clientMetrics: string[] =
-      props.settings.metricMode === MetricModes.Expression
-        ? props.settings.linkClientExpressions
-        : props.settings.linkClientMetrics;
-    const serverMetrics: string[] =
-      props.settings.metricMode === MetricModes.Expression
-        ? props.settings.linkServerExpressions
-        : props.settings.linkServerMetrics;
+    const clientMetrics: string[] = props.settings.linkClientExpressions;
+    const serverMetrics: string[] = props.settings.linkServerExpressions;
     const linkServerMetricConfig: MetricConfigOpt[] = 
props.settings.linkServerMetricConfig || [];
     const linkClientMetricConfig: MetricConfigOpt[] = 
props.settings.linkClientMetricConfig || [];
 
@@ -102,8 +94,10 @@ limitations under the License. -->
         {};
       if (metric) {
         const opt: MetricConfigOpt = linkServerMetricConfig[index] || {};
-        const v = aggregation(metric.value, opt);
-        return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${v} ${opt.unit || ""}</div>`;
+
+        return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${metric.value} ${
+          opt.unit || ""
+        }</div>`;
       }
     });
     const htmlClient = clientMetrics.map((m, index) => {
@@ -111,8 +105,8 @@ limitations under the License. -->
       const metric =
         topologyStore.linkClientMetrics[m].values.find((val: { id: string; 
value: unknown }) => val.id === data.id) ||
         {};
-      const v = aggregation(metric.value, opt);
-      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${v} ${opt.unit || ""}</div>`;
+
+      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${metric.value} ${opt.unit || ""}</div>`;
     });
     const html = [
       `<div>${data.sourceObj.serviceName} -> 
${data.targetObj.serviceName}</div>`,
@@ -124,17 +118,14 @@ limitations under the License. -->
   }
 
   function nodeTooltip(data: Node) {
-    const nodeMetrics: string[] =
-      props.settings.metricMode === MetricModes.Expression
-        ? props.settings.nodeExpressions
-        : props.settings.nodeMetrics;
+    const nodeMetrics: string[] = props.settings.nodeExpressions;
     const nodeMetricConfig = props.settings.nodeMetricConfig || [];
     const html = nodeMetrics.map((m, index) => {
       const metric =
         topologyStore.nodeMetricValue[m].values.find((val: { id: string; 
value: unknown }) => val.id === data.id) || {};
       const opt: MetricConfigOpt = nodeMetricConfig[index] || {};
-      const v = aggregation(metric.value, opt);
-      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${v} ${opt.unit || ""}</div>`;
+
+      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${metric.value} ${opt.unit || ""}</div>`;
     });
     return [` <div><span>name: </span>${data.serviceName}</div>`, 
...html].join(" ");
   }
diff --git a/src/views/dashboard/related/topology/service/HierarchyMap.vue 
b/src/views/dashboard/related/topology/service/HierarchyMap.vue
index 4f0265a7..6eb8c33d 100644
--- a/src/views/dashboard/related/topology/service/HierarchyMap.vue
+++ b/src/views/dashboard/related/topology/service/HierarchyMap.vue
@@ -43,7 +43,6 @@ limitations under the License. -->
   import router from "@/router";
   import { ElMessage } from "element-plus";
   import type { MetricConfigOpt } from "@/types/dashboard";
-  import { aggregation } from "@/hooks/useMetricsProcessor";
   import getDashboard from "@/hooks/useDashboardsSession";
   import Graph from "../components/Graph.vue";
 
@@ -137,8 +136,7 @@ limitations under the License. -->
           (val: { id: string; value: unknown }) => val.id === data.id,
         ) || {};
       const opt: MetricConfigOpt = nodeMetricConfig[index] || {};
-      const v = aggregation(metric.value, opt);
-      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${v} ${opt.unit || ""}</div>`;
+      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${metric.value} ${opt.unit || ""}</div>`;
     });
     const tipHtml = [
       `<div class="mb-5"><span class="grey">name: 
</span>${data.name}</div><div class="mb-5"><span class="grey">layer: 
</span>${data.layer}</div>`,
diff --git a/src/views/dashboard/related/topology/service/ServiceMap.vue 
b/src/views/dashboard/related/topology/service/ServiceMap.vue
index e6bb226e..10433cca 100644
--- a/src/views/dashboard/related/topology/service/ServiceMap.vue
+++ b/src/views/dashboard/related/topology/service/ServiceMap.vue
@@ -144,7 +144,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, MetricModes, CallTypes } from 
"@/views/dashboard/data";
+  import { EntityType, DepthList, CallTypes } from "@/views/dashboard/data";
   import router from "@/router";
   import { ElMessage } from "element-plus";
   import Settings from "../config/Settings.vue";
@@ -154,9 +154,7 @@ limitations under the License. -->
   import { useAppStoreWithOut } from "@/store/modules/app";
   import getDashboard from "@/hooks/useDashboardsSession";
   import type { MetricConfigOpt } from "@/types/dashboard";
-  import { aggregation } from "@/hooks/useMetricsProcessor";
   import icons from "@/assets/img/icons";
-  import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
   import { layout, computeLevels, changeNode } from 
"../components/utils/layout";
   import zoom from "@/views/dashboard/related/components/utils/zoom";
   import { useQueryTopologyExpressionsProcessor } from 
"@/hooks/useExpressionsProcessor";
@@ -231,15 +229,9 @@ limitations under the License. -->
   }
 
   async function update() {
-    if (settings.value.metricMode === MetricModes.Expression) {
-      topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
-      topologyStore.getLinkExpressions(settings.value.linkClientExpressions || 
[], CallTypes.Client);
-      topologyStore.getLinkExpressions(settings.value.linkServerExpressions || 
[], CallTypes.Server);
-    } else {
-      topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []);
-      topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || 
[]);
-      topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || 
[]);
-    }
+    topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []);
+    topologyStore.getLinkExpressions(settings.value.linkClientExpressions || 
[], CallTypes.Client);
+    topologyStore.getLinkExpressions(settings.value.linkServerExpressions || 
[], CallTypes.Server);
 
     window.addEventListener("resize", resize);
     await initLegendMetrics();
@@ -288,67 +280,33 @@ limitations under the License. -->
     if (!topologyStore.nodes.length) {
       return;
     }
-    if (settings.value.metricMode === MetricModes.Expression) {
-      const expression = props.config.legendMQE && 
props.config.legendMQE.expression;
-      if (!expression) {
-        return;
-      }
-      const { getExpressionQuery } = 
useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes);
-      const param = getExpressionQuery();
-      const res = await topologyStore.getNodeExpressionValue(param);
-      if (res.errors) {
-        ElMessage.error(res.errors);
-      } else {
-        topologyStore.setLegendValues([expression], res.data);
-      }
+
+    const expression = props.config.legendMQE && 
props.config.legendMQE.expression;
+    if (!expression) {
+      return;
+    }
+    const { getExpressionQuery } = 
useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes);
+    const param = getExpressionQuery();
+    const res = await topologyStore.getNodeExpressionValue(param);
+    if (res.errors) {
+      ElMessage.error(res.errors);
     } else {
-      const names = props.config.legend.map((d: any) => d.name);
-      if (!names.length) {
-        return;
-      }
-      const ids = topologyStore.nodes.map((d: Node) => d.id);
-      if (ids.length) {
-        const param = await useQueryTopologyMetrics(names, ids);
-        const res = await topologyStore.getLegendMetrics(param);
-        if (res.errors) {
-          ElMessage.error(res.errors);
-        }
-      }
+      topologyStore.setLegendValues([expression], res.data);
     }
   }
 
   function getNodeStatus(d: any) {
-    const { legend, legendMQE } = settings.value;
-    if (settings.value.metricMode === MetricModes.Expression) {
-      if (!legendMQE) {
-        return icons.CUBE;
-      }
-      if (!legendMQE.expression) {
-        return icons.CUBE;
-      }
-      return Number(d[legendMQE.expression]) && d.isReal ? icons.CUBEERROR : 
icons.CUBE;
-    }
-    if (!legend) {
+    const { legendMQE } = settings.value;
+    if (!legendMQE) {
       return icons.CUBE;
     }
-    if (!legend.length) {
+    if (!legendMQE.expression) {
       return icons.CUBE;
     }
-    let c = true;
-    for (const l of legend) {
-      if (l.condition === "<") {
-        c = c && d[l.name] < Number(l.value);
-      } else {
-        c = c && d[l.name] > Number(l.value);
-      }
-    }
-    return c && d.isReal ? icons.CUBEERROR : icons.CUBE;
+    return Number(d[legendMQE.expression]) && d.isReal ? icons.CUBEERROR : 
icons.CUBE;
   }
   function showNodeTip(event: MouseEvent, data: Node) {
-    const nodeMetrics: string[] =
-      (settings.value.metricMode === MetricModes.Expression
-        ? settings.value.nodeExpressions
-        : settings.value.nodeMetrics) || [];
+    const nodeMetrics: string[] = settings.value.nodeExpressions || [];
     const nodeMetricConfig = settings.value.nodeMetricConfig || [];
     const html = nodeMetrics.map((m, index) => {
       const metric =
@@ -356,8 +314,9 @@ limitations under the License. -->
           topologyStore.nodeMetricValue[m].values.find((val: { id: string; 
value: unknown }) => val.id === data.id)) ||
         {};
       const opt: MetricConfigOpt = nodeMetricConfig[index] || {};
-      const v = aggregation(metric.value, opt);
-      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${v} ${opt.unit || "unknown"}</div>`;
+      return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${metric.value} ${
+        opt.unit || "unknown"
+      }</div>`;
     });
     const tipHtml = [
       `<div class="mb-5"><span class="grey">name: </span>${
@@ -373,24 +332,19 @@ limitations under the License. -->
       .html(tipHtml);
   }
   function showLinkTip(event: MouseEvent, data: Call) {
-    const linkClientMetrics: string[] =
-      settings.value.metricMode === MetricModes.Expression
-        ? settings.value.linkClientExpressions
-        : settings.value.linkClientMetrics || [];
+    const linkClientMetrics: string[] = settings.value.linkClientExpressions 
|| [];
     const linkServerMetricConfig: MetricConfigOpt[] = 
settings.value.linkServerMetricConfig || [];
     const linkClientMetricConfig: MetricConfigOpt[] = 
settings.value.linkClientMetricConfig || [];
-    const linkServerMetrics: string[] =
-      settings.value.metricMode === MetricModes.Expression
-        ? settings.value.linkServerExpressions
-        : settings.value.linkServerMetrics || [];
+    const linkServerMetrics: string[] = settings.value.linkServerExpressions 
|| [];
     const htmlServer = linkServerMetrics.map((m, index) => {
       const metric = topologyStore.linkServerMetrics[m].values.find(
         (val: { id: string; value: unknown }) => val.id === data.id,
       );
       if (metric) {
         const opt: MetricConfigOpt = linkServerMetricConfig[index] || {};
-        const v = aggregation(metric.value, opt);
-        return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${v} ${opt.unit || ""}</div>`;
+        return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${metric.value} ${
+          opt.unit || ""
+        }</div>`;
       }
     });
     const htmlClient = linkClientMetrics.map((m: string, index: number) => {
@@ -399,8 +353,9 @@ limitations under the License. -->
         (val: { id: string; value: unknown }) => val.id === data.id,
       );
       if (metric) {
-        const v = aggregation(metric.value, opt);
-        return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${v} ${opt.unit || ""}</div>`;
+        return ` <div class="mb-5"><span class="grey">${opt.label || m}: 
</span>${metric.value} ${
+          opt.unit || ""
+        }</div>`;
       }
     });
     const html = [

Reply via email to