feat: enhance metric labels (#382)

This commit is contained in:
Fine0830 2024-04-10 16:40:14 +08:00 committed by GitHub
parent 8bc6761468
commit fd2c7ca716
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 44 additions and 37 deletions

View File

@ -117,16 +117,11 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
const label = results[0].metric && results[0].metric.labels[0] && results[0].metric.labels[0].value; const label = results[0].metric && results[0].metric.labels[0] && results[0].metric.labels[0].value;
source[c.label || label || name] = results[0].values.map((d: { value: unknown }) => d.value) || []; source[c.label || label || name] = results[0].values.map((d: { value: unknown }) => d.value) || [];
} else { } else {
const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
for (const item of results) { for (const item of results) {
const values = item.values.map((d: { value: unknown }) => d.value) || []; const values = item.values.map((d: { value: unknown }) => d.value) || [];
const index = item.metric.labels[0].value; const label = item.metric.labels.map((d: any) => `${d.key}=${d.value}`).join(",");
const indexNum = labels.findIndex((_, i: number) => i === Number(index));
if (labels[indexNum] && indexNum > -1) { source[label] = values;
source[labels[indexNum]] = values;
} else {
source[index] = values;
}
} }
} }
} }

View File

@ -100,8 +100,7 @@ const msg = {
import: "Import Dashboard Templates", import: "Import Dashboard Templates",
yes: "Yes", yes: "Yes",
no: "No", no: "No",
tableHeaderCol1: "Name of the first column of the table", tableHeaderCol2: "Name of the last column of the table",
tableHeaderCol2: "Name of the second column of the table",
showXAxis: "Show X Axis", showXAxis: "Show X Axis",
showYAxis: "Show Y Axis", showYAxis: "Show Y Axis",
nameError: "The dashboard name cannot be duplicate", nameError: "The dashboard name cannot be duplicate",

View File

@ -101,8 +101,7 @@ const msg = {
import: "Importar Plantilla Panel", import: "Importar Plantilla Panel",
yes: "Sí", yes: "Sí",
no: "No", no: "No",
tableHeaderCol1: "Nombre de la primera columna de la tabla", tableHeaderCol2: "Nombre de la Último columna de la tabla",
tableHeaderCol2: "Nombre de la segunda columna de la tabla",
showXAxis: "Mostrar Eje X", showXAxis: "Mostrar Eje X",
showYAxis: "Mostrar Eje Y", showYAxis: "Mostrar Eje Y",
nameError: "El nombre del panel no puede ser duplicado", nameError: "El nombre del panel no puede ser duplicado",

View File

@ -34,7 +34,8 @@ const titles = {
workflow_scheduler: "Flujo de trabajo", workflow_scheduler: "Flujo de trabajo",
workflow_scheduler_desc: "Proporcionar monitoreo para sistemas de programación de flujos de trabajo.", workflow_scheduler_desc: "Proporcionar monitoreo para sistemas de programación de flujos de trabajo.",
workflow_scheduler_airflow: "Airflow", workflow_scheduler_airflow: "Airflow",
workflow_scheduler_airflow_desc: "Observando tareas a través de los datos de telemetría recopilados desde Apache Airflow.", workflow_scheduler_airflow_desc:
"Observando tareas a través de los datos de telemetría recopilados desde Apache Airflow.",
// Service Mesh // Service Mesh
service_mesh: "Malla de Servicios", service_mesh: "Malla de Servicios",
service_mesh_desc: service_mesh_desc:

View File

@ -99,8 +99,7 @@ const msg = {
import: "导入仪表板模板", import: "导入仪表板模板",
yes: "是", yes: "是",
no: "否", no: "否",
tableHeaderCol1: "表格的第一列的名称", tableHeaderCol2: "表格的最后一列的名称",
tableHeaderCol2: "表格的第二列的名称",
showXAxis: "显示X轴", showXAxis: "显示X轴",
showYAxis: "显示Y轴", showYAxis: "显示Y轴",
nameError: "仪表板名称不能重复", nameError: "仪表板名称不能重复",

View File

@ -140,7 +140,6 @@ export interface TextConfig {
export interface TableConfig { export interface TableConfig {
type?: string; type?: string;
showTableValues: boolean; showTableValues: boolean;
tableHeaderCol1: string;
tableHeaderCol2: string; tableHeaderCol2: string;
} }

View File

@ -22,16 +22,6 @@ limitations under the License. -->
@change="updateConfig({ showTableValues })" @change="updateConfig({ showTableValues })"
/> />
</div> </div>
<div class="item">
<span class="label">{{ t("tableHeaderCol1") }}</span>
<el-input
class="input"
v-model="tableHeaderCol1"
size="small"
placeholder="none"
@change="updateConfig({ tableHeaderCol1 })"
/>
</div>
<div class="item"> <div class="item">
<span class="label">{{ t("tableHeaderCol2") }}</span> <span class="label">{{ t("tableHeaderCol2") }}</span>
<el-input <el-input
@ -52,7 +42,6 @@ limitations under the License. -->
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const graph = dashboardStore.selectedGrid.graph || {}; const graph = dashboardStore.selectedGrid.graph || {};
const showTableValues = ref(graph.showTableValues); const showTableValues = ref(graph.showTableValues);
const tableHeaderCol1 = ref(graph.tableHeaderCol1);
const tableHeaderCol2 = ref(graph.tableHeaderCol2); const tableHeaderCol2 = ref(graph.tableHeaderCol2);
function updateConfig(param: { [key: string]: unknown }) { function updateConfig(param: { [key: string]: unknown }) {

View File

@ -93,7 +93,6 @@ export const DefaultGraphConfig: { [key: string]: any } = {
Table: { Table: {
type: "Table", type: "Table",
showTableValues: true, showTableValues: true,
tableHeaderCol1: "",
tableHeaderCol2: "", tableHeaderCol2: "",
}, },
TopList: { TopList: {

View File

@ -16,17 +16,33 @@ limitations under the License. -->
<template> <template>
<div class="chart-table"> <div class="chart-table">
<div class="row header flex-h"> <div class="row header flex-h">
<div class="name" :style="`width: ${nameWidth}`"> <div
{{ config.tableHeaderCol1 || t("name") }} v-for="key in dataKeys[0]"
:key="key"
class="name"
:style="`width: ${dataKeys[0].length > 1 ? (nameWidth as number) / (dataKeys[0].length || 1) : nameWidth}%`"
>
{{ key.split("=")[0] || t("name") }}
</div> </div>
<div class="value-col" v-if="config.showTableValues"> <div class="value-col" v-if="config.showTableValues">
{{ config.tableHeaderCol2 || t("value") }} {{ config.tableHeaderCol2 || t("value") }}
</div> </div>
</div> </div>
<div class="row flex-h" v-for="key in dataKeys" :key="key"> <div class="row flex-h" v-for="(keys, index) in dataKeys" :key="index">
<div class="name" :style="`width: ${nameWidth}`">{{ key }}</div> <div
v-for="k in keys"
class="name"
:style="`width: ${keys.length > 1 ? (nameWidth as number) / (keys.length || 1) : nameWidth}%`"
:key="k"
>{{ k.split("=")[1] }}</div
>
<div class="value-col" v-if="config.showTableValues"> <div class="value-col" v-if="config.showTableValues">
{{ config.metricTypes[0] === "readMetricsValue" ? data[key] : data[key][data[key].length - 1 || 0] }} {{
(config.metricTypes && config.metricTypes[0] === "readMetricsValue") ||
(props.config.typesOfMQE && props.config.typesOfMQE[0] === ExpressionResultType.SINGLE_VALUE)
? data[keys[0]]
: data[(keys as string[]).join(",")][data[(keys as string[]).join(",")].length - 1 || 0]
}}
</div> </div>
</div> </div>
</div> </div>
@ -35,6 +51,7 @@ limitations under the License. -->
import { computed } from "vue"; import { computed } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { ExpressionResultType } from "@/views/dashboard/data";
/*global defineProps */ /*global defineProps */
const props = defineProps({ const props = defineProps({
data: { data: {
@ -45,24 +62,30 @@ limitations under the License. -->
type: Object as PropType<{ type: Object as PropType<{
showTableValues: boolean; showTableValues: boolean;
tableHeaderCol2: string; tableHeaderCol2: string;
tableHeaderCol1: string;
metricTypes: string[]; metricTypes: string[];
typesOfMQE: string[];
}>, }>,
default: () => ({ showTableValues: true }), default: () => ({ showTableValues: true }),
}, },
}); });
const { t } = useI18n(); const { t } = useI18n();
const nameWidth = computed(() => (props.config.showTableValues ? "80%" : "100%")); const nameWidth = computed(() => (props.config.showTableValues ? 80 : 100));
const dataKeys = computed(() => { const dataKeys = computed(() => {
if (props.config.metricTypes[0] === "readMetricsValue") { if (props.config.metricTypes && props.config.metricTypes[0] === "readMetricsValue") {
const keys = Object.keys(props.data || {});
return keys;
}
if (props.config.typesOfMQE && props.config.typesOfMQE[0] === ExpressionResultType.SINGLE_VALUE) {
const keys = Object.keys(props.data || {}); const keys = Object.keys(props.data || {});
return keys; return keys;
} }
const keys = Object.keys(props.data || {}).filter( const keys = Object.keys(props.data || {}).filter(
(i: string) => Array.isArray(props.data[i]) && props.data[i].length, (i: string) => Array.isArray(props.data[i]) && props.data[i].length,
); );
return keys; const list = keys.map((d: string) => d.split(","));
return list;
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -94,6 +117,10 @@ limitations under the License. -->
border-bottom: 1px solid $disabled-color; border-bottom: 1px solid $disabled-color;
} }
div:first-child {
border-bottom: 1px solid $disabled-color;
}
div:nth-last-child(2) { div:nth-last-child(2) {
border-bottom: 1px solid $disabled-color; border-bottom: 1px solid $disabled-color;
} }