You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2022/10/31 02:27:42 UTC
[skywalking-booster-ui] branch main updated: feat: support labeled value on the service/instance/endpoint list widgets (#177)
This is an automated email from the ASF dual-hosted git repository.
wusheng 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 09051e9 feat: support labeled value on the service/instance/endpoint list widgets (#177)
09051e9 is described below
commit 09051e916bb20233e0620e185a13e9aa1ef82dd1
Author: Fine0830 <fa...@gmail.com>
AuthorDate: Mon Oct 31 10:27:37 2022 +0800
feat: support labeled value on the service/instance/endpoint list widgets (#177)
---
src/hooks/useListConfig.ts | 16 ++--
src/hooks/useProcessor.ts | 88 +++++++++++++++++++---
src/types/dashboard.d.ts | 1 +
.../configuration/widget/metric/Index.vue | 16 ++--
.../configuration/widget/metric/Standard.vue | 4 +-
src/views/dashboard/controls/Widget.vue | 2 +-
src/views/dashboard/graphs/EndpointList.vue | 55 ++++++++------
src/views/dashboard/graphs/InstanceList.vue | 58 ++++++++------
src/views/dashboard/graphs/Line.vue | 6 +-
src/views/dashboard/graphs/ServiceList.vue | 71 ++++++++++-------
.../dashboard/graphs/components/ColumnGraph.vue | 26 +++++--
11 files changed, 235 insertions(+), 108 deletions(-)
diff --git a/src/hooks/useListConfig.ts b/src/hooks/useListConfig.ts
index a7f7ad5..c87fd39 100644
--- a/src/hooks/useListConfig.ts
+++ b/src/hooks/useListConfig.ts
@@ -26,14 +26,18 @@ export function useListConfig(config: any, index: string) {
config.metricConfig &&
config.metricConfig[i] &&
config.metricConfig[i].calculation;
- const line =
- config.metricTypes[i] === MetricQueryTypes.ReadMetricsValues &&
- !types.includes(calculation);
+ const isLinear =
+ [
+ MetricQueryTypes.ReadMetricsValues,
+ MetricQueryTypes.ReadLabeledMetricsValues,
+ ].includes(config.metricTypes[i]) && !types.includes(calculation);
const isAvg =
- config.metricTypes[i] === MetricQueryTypes.ReadMetricsValues &&
- types.includes(calculation);
+ [
+ MetricQueryTypes.ReadMetricsValues,
+ MetricQueryTypes.ReadLabeledMetricsValues,
+ ].includes(config.metricTypes[i]) && types.includes(calculation);
return {
- isLinear: line,
+ isLinear,
isAvg,
};
}
diff --git a/src/hooks/useProcessor.ts b/src/hooks/useProcessor.ts
index d730189..97b22e4 100644
--- a/src/hooks/useProcessor.ts
+++ b/src/hooks/useProcessor.ts
@@ -154,6 +154,7 @@ export function useQueryProcessor(config: any) {
}
});
const queryStr = `query queryData(${variables}) {${fragment}}`;
+
return {
queryStr,
conditions,
@@ -254,13 +255,19 @@ export function useSourceProcessor(
export function useQueryPodsMetrics(
pods: Array<Instance | Endpoint | Service | any>,
- config: { metrics: string[]; metricTypes: string[] },
+ config: {
+ metrics: string[];
+ metricTypes: string[];
+ metricConfig: MetricConfigOpt[];
+ },
scope: string
) {
- if (!(config.metrics && config.metrics[0])) {
+ const metricTypes = (config.metricTypes || []).filter((m: string) => m);
+ if (!metricTypes.length) {
return;
}
- if (!(config.metricTypes && config.metricTypes[0])) {
+ const metrics = (config.metrics || []).filter((m: string) => m);
+ if (!metrics.length) {
return;
}
const appStore = useAppStoreWithOut();
@@ -282,14 +289,24 @@ export function useQueryPodsMetrics(
endpointName: scope === "Endpoint" ? d.label : undefined,
normal: scope === "Service" ? d.normal : currentService.normal,
};
- const f = config.metrics.map((name: string, idx: number) => {
- const metricType = config.metricTypes[idx] || "";
+ 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,
};
- variables.push(`$condition${index}${idx}: MetricsCondition!`);
- return `${name}${index}${idx}: ${metricType}(condition: $condition${index}${idx}, duration: $duration)${RespFields[metricType]}`;
+ 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;
+ }
+ return `${name}${index}${idx}: ${metricType}(condition: $condition${index}${idx}, ${labelStr}duration: $duration)${RespFields[metricType]}`;
});
return f;
}
@@ -299,6 +316,7 @@ export function useQueryPodsMetrics(
return { queryStr, conditions };
}
+
export function usePodsSource(
pods: Array<Instance | Endpoint>,
resp: { errors: string; data: { [key: string]: any } },
@@ -312,12 +330,20 @@ export function usePodsSource(
ElMessage.error(resp.errors);
return {};
}
+ const names: string[] = [];
+ const metricConfigArr: MetricConfigOpt[] = [];
+ const metricTypesArr: string[] = [];
const data = pods.map((d: Instance | 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) {
d[name] = aggregation(resp.data[key], c);
+ if (idx === 0) {
+ names.push(name);
+ metricConfigArr.push(c);
+ metricTypesArr.push(config.metricTypes[index]);
+ }
}
if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValues) {
d[name] = {};
@@ -333,12 +359,56 @@ export function usePodsSource(
d[name]["values"] = resp.data[key].values.values.map(
(val: { value: number }) => 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 }) =>
+ 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;
+ return { data, names, metricConfigArr, metricTypesArr };
}
export function useQueryTopologyMetrics(metrics: string[], ids: string[]) {
const appStore = useAppStoreWithOut();
diff --git a/src/types/dashboard.d.ts b/src/types/dashboard.d.ts
index b82afe9..ceabab3 100644
--- a/src/types/dashboard.d.ts
+++ b/src/types/dashboard.d.ts
@@ -74,6 +74,7 @@ export type MetricConfigOpt = {
labelsIndex: string;
sortOrder: string;
topN?: number;
+ index?: number;
};
export interface WidgetConfig {
diff --git a/src/views/dashboard/configuration/widget/metric/Index.vue b/src/views/dashboard/configuration/widget/metric/Index.vue
index 233eb8a..cdb31f0 100644
--- a/src/views/dashboard/configuration/widget/metric/Index.vue
+++ b/src/views/dashboard/configuration/widget/metric/Index.vue
@@ -191,7 +191,10 @@ async function setMetricType(chart?: any) {
states.metricList = (arr || []).filter(
(d: { catalog: string; type: string }) => {
if (states.isList) {
- if (d.type === MetricsType.REGULAR_VALUE) {
+ if (
+ d.type === MetricsType.REGULAR_VALUE ||
+ d.type === MetricsType.LABELED_VALUE
+ ) {
return d;
}
} else if (g.type === "Table") {
@@ -239,7 +242,10 @@ async function setMetricType(chart?: any) {
}
function setDashboards(type?: string) {
- const chart = type || dashboardStore.selectedGrid.graph || {};
+ const chart =
+ type ||
+ (dashboardStore.selectedGrid.graph &&
+ dashboardStore.selectedGrid.graph.type);
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
const arr = list.reduce(
(
@@ -248,9 +254,9 @@ function setDashboards(type?: string) {
) => {
if (d.layer === dashboardStore.layerId) {
if (
- (d.entity === EntityType[0].value && chart.type === "ServiceList") ||
- (d.entity === EntityType[2].value && chart.type === "EndpointList") ||
- (d.entity === EntityType[3].value && chart.type === "InstanceList")
+ (d.entity === EntityType[0].value && chart === "ServiceList") ||
+ (d.entity === EntityType[2].value && chart === "EndpointList") ||
+ (d.entity === EntityType[3].value && chart === "InstanceList")
) {
prev.push({
...d,
diff --git a/src/views/dashboard/configuration/widget/metric/Standard.vue b/src/views/dashboard/configuration/widget/metric/Standard.vue
index 150c220..1ba282c 100644
--- a/src/views/dashboard/configuration/widget/metric/Standard.vue
+++ b/src/views/dashboard/configuration/widget/metric/Standard.vue
@@ -115,7 +115,9 @@ const currentMetric = ref<MetricConfigOpt>({
topN: props.currentMetricConfig.topN || 10,
});
const metricTypes = dashboardStore.selectedGrid.metricTypes || [];
-const metricType = ref<string>(metricTypes[props.index]);
+const metricType = computed(
+ () => (dashboardStore.selectedGrid.metricTypes || [])[props.index]
+);
const hasLabel = computed(() => {
const graph = dashboardStore.selectedGrid.graph || {};
return (
diff --git a/src/views/dashboard/controls/Widget.vue b/src/views/dashboard/controls/Widget.vue
index f723984..8593d43 100644
--- a/src/views/dashboard/controls/Widget.vue
+++ b/src/views/dashboard/controls/Widget.vue
@@ -62,7 +62,7 @@ limitations under the License. -->
metricTypes: data.metricTypes || [''],
i: data.i,
id: data.id,
- metricConfig: data.metricConfig,
+ metricConfig: data.metricConfig || [],
filters: data.filters || {},
relatedTrace: data.relatedTrace || {},
}"
diff --git a/src/views/dashboard/graphs/EndpointList.vue b/src/views/dashboard/graphs/EndpointList.vue
index c4654b2..138865c 100644
--- a/src/views/dashboard/graphs/EndpointList.vue
+++ b/src/views/dashboard/graphs/EndpointList.vue
@@ -31,7 +31,7 @@ limitations under the License. -->
</div>
<div class="list">
<el-table v-loading="chartLoading" :data="endpoints" style="width: 100%">
- <el-table-column label="Endpoints">
+ <el-table-column label="Endpoints" fixed min-width="220">
<template #default="scope">
<span
class="link"
@@ -45,7 +45,12 @@ limitations under the License. -->
<ColumnGraph
:intervalTime="intervalTime"
:colMetrics="colMetrics"
- :config="config"
+ :config="{
+ ...config,
+ metrics: colMetrics,
+ metricConfig,
+ metricTypes,
+ }"
v-if="colMetrics.length"
/>
</el-table>
@@ -53,7 +58,7 @@ limitations under the License. -->
</div>
</template>
<script setup lang="ts">
-import { ref, watch, computed } from "vue";
+import { ref, watch } from "vue";
import { useSelectorStore } from "@/store/modules/selectors";
import { ElMessage } from "element-plus";
import { useI18n } from "vue-i18n";
@@ -99,9 +104,9 @@ const dashboardStore = useDashboardStore();
const chartLoading = ref<boolean>(false);
const endpoints = ref<Endpoint[]>([]);
const searchText = ref<string>("");
-const colMetrics = computed(() =>
- (props.config.metrics || []).filter((d: string) => d)
-);
+const colMetrics = ref<string[]>([]);
+const metricConfig = ref<MetricConfigOpt[]>(props.config.metricConfig || []);
+const metricTypes = ref<string[]>(props.config.metricTypes || []);
if (props.needQuery) {
queryEndpoints();
@@ -125,8 +130,8 @@ async function queryEndpointMetrics(currentPods: Endpoint[]) {
return;
}
const metrics = props.config.metrics || [];
- const metricTypes = props.config.metricTypes || [];
- if (metrics.length && metrics[0] && metricTypes.length && metricTypes[0]) {
+ const types = props.config.metricTypes || [];
+ if (metrics.length && metrics[0] && types.length && types[0]) {
const params = await useQueryPodsMetrics(
currentPods,
props.config,
@@ -138,12 +143,18 @@ async function queryEndpointMetrics(currentPods: Endpoint[]) {
ElMessage.error(json.errors);
return;
}
- const metricConfig = props.config.metricConfig || [];
-
- endpoints.value = usePodsSource(currentPods, json, {
- ...props.config,
- metricConfig: metricConfig,
- });
+ 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;
@@ -166,11 +177,16 @@ async function searchList() {
await queryEndpoints();
}
watch(
- () => [...(props.config.metricTypes || []), ...(props.config.metrics || [])],
+ () => [
+ ...(props.config.metricTypes || []),
+ ...(props.config.metrics || []),
+ ...(props.config.metricConfig || []),
+ ],
(data, old) => {
if (JSON.stringify(data) === JSON.stringify(old)) {
return;
}
+ metricConfig.value = props.config.metricConfig;
queryEndpointMetrics(endpoints.value);
}
);
@@ -180,15 +196,6 @@ watch(
queryEndpoints();
}
);
-watch(
- () => [...(props.config.metricConfig || [])],
- (data, old) => {
- if (JSON.stringify(data) === JSON.stringify(old)) {
- return;
- }
- queryEndpointMetrics(endpoints.value);
- }
-);
</script>
<style lang="scss" scoped>
@import "./style.scss";
diff --git a/src/views/dashboard/graphs/InstanceList.vue b/src/views/dashboard/graphs/InstanceList.vue
index 04ae541..2963102 100644
--- a/src/views/dashboard/graphs/InstanceList.vue
+++ b/src/views/dashboard/graphs/InstanceList.vue
@@ -30,7 +30,7 @@ limitations under the License. -->
</div>
<div class="list">
<el-table v-loading="chartLoading" :data="instances" style="width: 100%">
- <el-table-column label="Service Instances">
+ <el-table-column label="Service Instances" fixed min-width="320">
<template #default="scope">
<span
class="link"
@@ -42,12 +42,17 @@ limitations under the License. -->
</template>
</el-table-column>
<ColumnGraph
- v-if="colMetrics.length"
:intervalTime="intervalTime"
:colMetrics="colMetrics"
- :config="config"
+ :config="{
+ ...config,
+ metrics: colMetrics,
+ metricConfig,
+ metricTypes,
+ }"
+ v-if="colMetrics.length"
/>
- <el-table-column label="Attributes">
+ <el-table-column label="Attributes" fixed="right" min-width="100">
<template #default="scope">
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
@@ -82,7 +87,7 @@ limitations under the License. -->
</div>
</template>
<script setup lang="ts">
-import { ref, watch, computed } from "vue";
+import { ref, watch } from "vue";
import { useI18n } from "vue-i18n";
import { ElMessage } from "element-plus";
import type { PropType } from "vue";
@@ -126,9 +131,9 @@ const chartLoading = ref<boolean>(false);
const instances = ref<Instance[]>([]); // current instances
const pageSize = 10;
const searchText = ref<string>("");
-const colMetrics = computed(() =>
- (props.config.metrics || []).filter((d: string) => d)
-);
+const colMetrics = ref<string[]>([]);
+const metricConfig = ref<MetricConfigOpt[]>(props.config.metricConfig || []);
+const metricTypes = ref<string[]>(props.config.metricTypes || []);
if (props.needQuery) {
queryInstance();
}
@@ -154,9 +159,9 @@ async function queryInstanceMetrics(currentInstances: Instance[]) {
return;
}
const metrics = props.config.metrics || [];
- const metricTypes = props.config.metricTypes || [];
+ const types = props.config.metricTypes || [];
- if (metrics.length && metrics[0] && metricTypes.length && metricTypes[0]) {
+ if (metrics.length && metrics[0] && types.length && types[0]) {
const params = await useQueryPodsMetrics(
currentInstances,
props.config,
@@ -168,11 +173,18 @@ async function queryInstanceMetrics(currentInstances: Instance[]) {
ElMessage.error(json.errors);
return;
}
- const metricConfig = props.config.metricConfig || [];
- instances.value = usePodsSource(currentInstances, json, {
- ...props.config,
- metricConfig,
- });
+ 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;
@@ -215,11 +227,16 @@ function searchList() {
}
watch(
- () => [...(props.config.metricTypes || []), ...(props.config.metrics || [])],
+ () => [
+ ...(props.config.metricTypes || []),
+ ...(props.config.metrics || []),
+ ...(props.config.metricConfig || []),
+ ],
(data, old) => {
if (JSON.stringify(data) === JSON.stringify(old)) {
return;
}
+ metricConfig.value = props.config.metricConfig;
queryInstanceMetrics(instances.value);
}
);
@@ -229,15 +246,6 @@ watch(
queryInstance();
}
);
-watch(
- () => [...(props.config.metricConfig || [])],
- (data, old) => {
- if (JSON.stringify(data) === JSON.stringify(old)) {
- return;
- }
- queryInstanceMetrics(instances.value);
- }
-);
</script>
<style lang="scss" scoped>
@import "./style.scss";
diff --git a/src/views/dashboard/graphs/Line.vue b/src/views/dashboard/graphs/Line.vue
index d1c3d82..ae27ff7 100644
--- a/src/views/dashboard/graphs/Line.vue
+++ b/src/views/dashboard/graphs/Line.vue
@@ -42,9 +42,9 @@ const props = defineProps({
config: {
type: Object as PropType<
LineConfig & {
- filters: Filters;
- relatedTrace: RelatedTrace;
- } & { id: string }
+ filters?: Filters;
+ relatedTrace?: RelatedTrace;
+ } & { id?: string }
>,
default: () => ({
step: false,
diff --git a/src/views/dashboard/graphs/ServiceList.vue b/src/views/dashboard/graphs/ServiceList.vue
index a08d22c..3a59762 100644
--- a/src/views/dashboard/graphs/ServiceList.vue
+++ b/src/views/dashboard/graphs/ServiceList.vue
@@ -37,12 +37,17 @@ limitations under the License. -->
:border="true"
:style="{ fontSize: '14px' }"
>
- <el-table-column label="Service Groups" v-if="config.showGroup">
+ <el-table-column
+ fixed
+ label="Service Groups"
+ v-if="config.showGroup"
+ min-width="150"
+ >
<template #default="scope">
{{ scope.row.group }}
</template>
</el-table-column>
- <el-table-column label="Service Names">
+ <el-table-column fixed label="Service Names" min-width="220">
<template #default="scope">
<span
class="link"
@@ -56,7 +61,12 @@ limitations under the License. -->
<ColumnGraph
:intervalTime="intervalTime"
:colMetrics="colMetrics"
- :config="config"
+ :config="{
+ ...config,
+ metrics: colMetrics,
+ metricConfig,
+ metricTypes,
+ }"
v-if="colMetrics.length"
/>
</el-table>
@@ -75,7 +85,7 @@ limitations under the License. -->
</div>
</template>
<script setup lang="ts">
-import { watch, ref, computed } from "vue";
+import { watch, ref } from "vue";
import { ElMessage } from "element-plus";
import type { PropType } from "vue";
import { ServiceListConfig } from "@/types/dashboard";
@@ -102,7 +112,9 @@ const props = defineProps({
metrics: string[];
metricTypes: string[];
isEdit: boolean;
- } & { metricConfig: MetricConfigOpt[] }
+ names: string[];
+ metricConfig: MetricConfigOpt[];
+ }
>,
default: () => ({ dashboardName: "", fontSize: 12 }),
},
@@ -115,12 +127,13 @@ const appStore = useAppStoreWithOut();
const chartLoading = ref<boolean>(false);
const pageSize = 10;
const services = ref<Service[]>([]);
+const colMetrics = ref<string[]>([]);
const searchText = ref<string>("");
const groups = ref<any>({});
const sortServices = ref<(Service & { merge: boolean })[]>([]);
-const colMetrics = computed(() =>
- (props.config.metrics || []).filter((d: string) => d)
-);
+const metricConfig = ref<MetricConfigOpt[]>(props.config.metricConfig || []);
+const metricTypes = ref<string[]>(props.config.metricTypes || []);
+
queryServices();
async function queryServices() {
@@ -198,12 +211,12 @@ async function queryServiceMetrics(currentServices: Service[]) {
return;
}
const metrics = props.config.metrics || [];
- const metricTypes = props.config.metricTypes || [];
+ const types = props.config.metricTypes || [];
- if (metrics.length && metrics[0] && metricTypes.length && metricTypes[0]) {
+ if (metrics.length && metrics[0] && types.length && types[0]) {
const params = await useQueryPodsMetrics(
currentServices,
- props.config,
+ { ...props.config, metricConfig: metricConfig.value || [] },
EntityType[0].value
);
const json = await dashboardStore.fetchMetricValue(params);
@@ -212,14 +225,22 @@ async function queryServiceMetrics(currentServices: Service[]) {
ElMessage.error(json.errors);
return;
}
- const metricConfig = props.config.metricConfig || [];
- services.value = usePodsSource(currentServices, json, {
- ...props.config,
- metricConfig: metricConfig || [],
- });
+
+ 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;
}
function objectSpanMethod(param: any): any {
@@ -257,20 +278,16 @@ function searchList() {
}
watch(
- () => [...(props.config.metricTypes || []), ...(props.config.metrics || [])],
- (data, old) => {
- if (JSON.stringify(data) === JSON.stringify(old)) {
- return;
- }
- queryServiceMetrics(services.value);
- }
-);
-watch(
- () => [...(props.config.metricConfig || [])],
+ () => [
+ ...(props.config.metricTypes || []),
+ ...(props.config.metrics || []),
+ ...(props.config.metricConfig || []),
+ ],
(data, old) => {
if (JSON.stringify(data) === JSON.stringify(old)) {
return;
}
+ metricConfig.value = props.config.metricConfig;
queryServiceMetrics(services.value);
}
);
diff --git a/src/views/dashboard/graphs/components/ColumnGraph.vue b/src/views/dashboard/graphs/components/ColumnGraph.vue
index c5086e5..d57bfbe 100644
--- a/src/views/dashboard/graphs/components/ColumnGraph.vue
+++ b/src/views/dashboard/graphs/components/ColumnGraph.vue
@@ -20,6 +20,7 @@ limitations under the License. -->
getLabel(metric, index)
)} ${decodeURIComponent(getUnit(index))}`"
:key="metric + index"
+ min-width="150"
>
<template #default="scope">
<div class="chart">
@@ -90,18 +91,18 @@ import { MetricConfigOpt } from "@/types/dashboard";
import { useListConfig } from "@/hooks/useListConfig";
import Line from "../Line.vue";
import Card from "../Card.vue";
+import { MetricQueryTypes } from "@/hooks/data";
/*global defineProps */
const props = defineProps({
colMetrics: { type: Object },
config: {
- type: Object as PropType<
- {
- i: string;
- metrics: string[];
- metricTypes: string[];
- } & { metricConfig: MetricConfigOpt[] }
- >,
+ type: Object as PropType<{
+ i: string;
+ metrics: string[];
+ metricTypes: string[];
+ metricConfig: MetricConfigOpt[];
+ }>,
default: () => ({}),
},
intervalTime: { type: Array as PropType<string[]>, default: () => [] },
@@ -125,6 +126,16 @@ function getLabel(metric: string, index: string) {
props.config.metricConfig[i] &&
props.config.metricConfig[i].label;
if (label) {
+ if (
+ props.config.metricTypes[i] === MetricQueryTypes.ReadLabeledMetricsValues
+ ) {
+ const name = (label || "")
+ .split(",")
+ .map((item: string) => item.replace(/^\s*|\s*$/g, ""))[
+ props.config.metricConfig[i].index || 0
+ ];
+ return encodeURIComponent(name || "");
+ }
return encodeURIComponent(label);
}
return encodeURIComponent(metric);
@@ -157,5 +168,6 @@ function getLabel(metric: string, index: string) {
display: inline-block;
flex-grow: 2;
height: 100%;
+ width: calc(100% - 30px);
}
</style>