add metric config

This commit is contained in:
Qiuxia Fan 2022-03-25 20:51:50 +08:00
parent aa91cbfe53
commit 19715d7152
14 changed files with 222 additions and 196 deletions

View File

@ -0,0 +1,17 @@
<!-- 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. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M6.984 9.984h10.031l-5.016 5.016z"></path>
</svg>

After

Width:  |  Height:  |  Size: 922 B

View File

@ -13,6 +13,5 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>cancel</title>
<path d="M17.016 15.609l-3.609-3.609 3.609-3.609-1.406-1.406-3.609 3.609-3.609-3.609-1.406 1.406 3.609 3.609-3.609 3.609 1.406 1.406 3.609-3.609 3.609 3.609zM12 2.016q4.125 0 7.055 2.93t2.93 7.055-2.93 7.055-7.055 2.93-7.055-2.93-2.93-7.055 2.93-7.055 7.055-2.93z"></path> <path d="M17.016 15.609l-3.609-3.609 3.609-3.609-1.406-1.406-3.609 3.609-3.609-3.609-1.406 1.406 3.609 3.609-3.609 3.609 1.406 1.406 3.609-3.609 3.609 3.609zM12 2.016q4.125 0 7.055 2.93t2.93 7.055-2.93 7.055-7.055 2.93-7.055-2.93-2.93-7.055 2.93-7.055 7.055-2.93z"></path>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -13,6 +13,5 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>clearclose</title>
<path d="M18.984 6.422l-5.578 5.578 5.578 5.578-1.406 1.406-5.578-5.578-5.578 5.578-1.406-1.406 5.578-5.578-5.578-5.578 1.406-1.406 5.578 5.578 5.578-5.578z"></path> <path d="M18.984 6.422l-5.578 5.578 5.578 5.578-1.406 1.406-5.578-5.578-5.578 5.578-1.406-1.406 5.578-5.578-5.578-5.578 1.406-1.406 5.578 5.578 5.578-5.578z"></path>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -13,6 +13,5 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>createmode_editedit</title>
<path d="M20.719 7.031l-1.828 1.828-3.75-3.75 1.828-1.828q0.281-0.281 0.703-0.281t0.703 0.281l2.344 2.344q0.281 0.281 0.281 0.703t-0.281 0.703zM3 17.25l11.063-11.063 3.75 3.75-11.063 11.063h-3.75v-3.75z"></path> <path d="M20.719 7.031l-1.828 1.828-3.75-3.75 1.828-1.828q0.281-0.281 0.703-0.281t0.703 0.281l2.344 2.344q0.281 0.281 0.281 0.703t-0.281 0.703zM3 17.25l11.063-11.063 3.75 3.75-11.063 11.063h-3.75v-3.75z"></path>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -22,6 +22,14 @@ export enum MetricQueryTypes {
READHEATMAP = "readHeatMap", READHEATMAP = "readHeatMap",
ReadSampledRecords = "readSampledRecords", ReadSampledRecords = "readSampledRecords",
} }
export enum Calculations {
Percentage = "percentage",
ByteToKB = "byteToKB",
Apdex = "apdex",
ConvertSeconds = "convertSeconds",
ConvertMilliseconds = "convertMilliseconds",
}
export enum sizeEnum { export enum sizeEnum {
XS = "XS", XS = "XS",
SM = "SM", SM = "SM",

View File

@ -15,13 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import dayjs from "dayjs"; import dayjs from "dayjs";
import { RespFields, MetricQueryTypes } from "./data"; import { RespFields, MetricQueryTypes, Calculations } from "./data";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { Instance, Endpoint, Service } from "@/types/selector"; import { Instance, Endpoint, Service } from "@/types/selector";
import { StandardConfig } from "@/types/dashboard"; import { MetricConfigOpt } from "@/types/dashboard";
export function useQueryProcessor(config: any) { export function useQueryProcessor(config: any) {
if (!(config.metrics && config.metrics[0])) { if (!(config.metrics && config.metrics[0])) {
@ -48,6 +48,7 @@ export function useQueryProcessor(config: any) {
} }
const fragment = config.metrics.map((name: string, index: number) => { const fragment = config.metrics.map((name: string, index: number) => {
const metricType = config.metricTypes[index] || ""; const metricType = config.metricTypes[index] || "";
const c = (config.metricConfig && config.metricConfig[index]) || {};
if ( if (
[ [
MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.ReadSampledRecords,
@ -63,7 +64,7 @@ export function useQueryProcessor(config: any) {
normal: selectorStore.currentService.normal, normal: selectorStore.currentService.normal,
scope: dashboardStore.entity, scope: dashboardStore.entity,
topN: 10, topN: 10,
order: config.standard.sortOrder || "DES", order: c.sortOrder || "DES",
}; };
} else { } else {
if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) { if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
@ -128,7 +129,7 @@ export function useSourceProcessor(
config: { config: {
metrics: string[]; metrics: string[];
metricTypes: string[]; metricTypes: string[];
standard: StandardConfig; metricConfig: MetricConfigOpt[];
} }
) { ) {
if (resp.errors) { if (resp.errors) {
@ -140,23 +141,24 @@ export function useSourceProcessor(
config.metricTypes.forEach((type: string, index) => { config.metricTypes.forEach((type: string, index) => {
const m = config.metrics[index]; const m = config.metrics[index];
const c = (config.metricConfig && config.metricConfig[index]) || {};
if (type === MetricQueryTypes.ReadMetricsValues) { if (type === MetricQueryTypes.ReadMetricsValues) {
source[m] = resp.data[keys[index]].values.values.map( source[m] = resp.data[keys[index]].values.values.map(
(d: { value: number }) => aggregation(d.value, config.standard) (d: { value: number }) => aggregation(d.value, c)
); );
} }
if (type === MetricQueryTypes.ReadLabeledMetricsValues) { if (type === MetricQueryTypes.ReadLabeledMetricsValues) {
const resVal = Object.values(resp.data)[0] || []; const resVal = Object.values(resp.data)[0] || [];
const labels = (config.standard.metricLabels || "") const labels = (c.label || "")
.split(",") .split(",")
.map((item: string) => item.replace(/^\s*|\s*$/g, "")); .map((item: string) => item.replace(/^\s*|\s*$/g, ""));
const labelsIdx = (config.standard.labelsIndex || "") const labelsIdx = (c.labelsIndex || "")
.split(",") .split(",")
.map((item: string) => item.replace(/^\s*|\s*$/g, "")); .map((item: string) => item.replace(/^\s*|\s*$/g, ""));
for (const item of resVal) { for (const item of resVal) {
const values = item.values.values.map((d: { value: number }) => const values = item.values.values.map((d: { value: number }) =>
aggregation(Number(d.value), config.standard) aggregation(Number(d.value), c)
); );
const indexNum = labelsIdx.findIndex((d: string) => d === item.label); const indexNum = labelsIdx.findIndex((d: string) => d === item.label);
@ -168,10 +170,7 @@ export function useSourceProcessor(
} }
} }
if (type === MetricQueryTypes.ReadMetricsValue) { if (type === MetricQueryTypes.ReadMetricsValue) {
source[m] = aggregation( source[m] = aggregation(Number(Object.values(resp.data)[0]), c);
Number(Object.values(resp.data)[0]),
config.standard
);
} }
if ( if (
type === MetricQueryTypes.SortMetrics || type === MetricQueryTypes.SortMetrics ||
@ -179,7 +178,7 @@ export function useSourceProcessor(
) { ) {
source[m] = (Object.values(resp.data)[0] || []).map( source[m] = (Object.values(resp.data)[0] || []).map(
(d: { value: unknown; name: string }) => { (d: { value: unknown; name: string }) => {
d.value = aggregation(Number(d.value), config.standard); d.value = aggregation(Number(d.value), c);
return d; return d;
} }
@ -307,33 +306,28 @@ export function useQueryTopologyMetrics(metrics: string[], ids: string[]) {
return { queryStr, conditions }; return { queryStr, conditions };
} }
function aggregation(val: number, standard: any): number | string { function aggregation(val: number, config: any): number | string {
let data: number | string = val; let data: number | string = val;
if (!isNaN(standard.plus)) { switch (config.calculation) {
data = val + Number(standard.plus); case Calculations.Percentage:
return data; data = val / 100;
} break;
if (!isNaN(standard.minus)) { case Calculations.ByteToKB:
data = val - Number(standard.plus); data = val / 1024;
return data; break;
} case Calculations.Apdex:
if (!isNaN(standard.multiply) && standard.divide !== 0) { data = val / 10000;
data = val * Number(standard.multiply); break;
return data; case Calculations.ConvertSeconds:
}
if (!isNaN(standard.divide) && standard.divide !== 0) {
data = val / Number(standard.divide);
return data;
}
if (standard.milliseconds) {
data = dayjs(val).format("YYYY-MM-DD HH:mm:ss"); data = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
return data; break;
} case Calculations.ConvertMilliseconds:
if (standard.milliseconds) {
data = dayjs.unix(val).format("YYYY-MM-DD HH:mm:ss"); data = dayjs.unix(val).format("YYYY-MM-DD HH:mm:ss");
return data; break;
default:
data;
break;
} }
return data; return data;
} }

View File

@ -127,6 +127,7 @@ const msg = {
kubernetes: "Kubernetes", kubernetes: "Kubernetes",
textUrl: "Text Hyperlink", textUrl: "Text Hyperlink",
textAlign: "Text Align", textAlign: "Text Align",
metricLabel: "Metric Label",
hourTip: "Select Hour", hourTip: "Select Hour",
minuteTip: "Select Minute", minuteTip: "Select Minute",
secondTip: "Select Second", secondTip: "Select Second",
@ -259,7 +260,7 @@ const msg = {
independentSelector: "Selectors", independentSelector: "Selectors",
unknownMetrics: "Unknown Metrics", unknownMetrics: "Unknown Metrics",
labels: "Labels", labels: "Labels",
aggregation: "Data Calculation", aggregation: "Calculation",
unit: "Unit", unit: "Unit",
labelsIndex: "Label Subscript", labelsIndex: "Label Subscript",
parentService: "Parent Service", parentService: "Parent Service",

View File

@ -127,6 +127,7 @@ const msg = {
kubernetes: "Kubernetes", kubernetes: "Kubernetes",
textUrl: "文本超链接", textUrl: "文本超链接",
textAlign: "文本对齐", textAlign: "文本对齐",
metricLabel: "指标标签",
hourTip: "选择小时", hourTip: "选择小时",
minuteTip: "选择分钟", minuteTip: "选择分钟",
secondTip: "选择秒数", secondTip: "选择秒数",
@ -261,7 +262,7 @@ const msg = {
independentSelector: "独立选择器", independentSelector: "独立选择器",
unknownMetrics: "未知指标", unknownMetrics: "未知指标",
labels: "标签", labels: "标签",
aggregation: "数据计算", aggregation: "计算",
unit: "单位", unit: "单位",
labelsIndex: "标签下标", labelsIndex: "标签下标",
parentService: "父级服务", parentService: "父级服务",

View File

@ -28,6 +28,7 @@ export const NewControl = {
standard: {}, standard: {},
metrics: [""], metrics: [""],
metricTypes: [""], metricTypes: [""],
metricConfig: [],
}; };
export const TextConfig = { export const TextConfig = {
fontColor: "white", fontColor: "white",

View File

@ -36,8 +36,17 @@ export interface LayoutConfig {
metricTypes: string[]; metricTypes: string[];
children?: any; children?: any;
activedTabIndex?: number; activedTabIndex?: number;
metricConfig?: MetricConfigOpt[];
} }
export type MetricConfigOpt = {
unit: string;
label: string;
calculation: string;
labelsIndex: string;
sortOrder: string;
};
export interface WidgetConfig { export interface WidgetConfig {
title?: string; title?: string;
tips?: string; tips?: string;

View File

@ -49,6 +49,14 @@ limitations under the License. -->
@change="changeMetricType(index, $event)" @change="changeMetricType(index, $event)"
class="selectors" class="selectors"
/> />
<el-popover placement="top" :width="400" :visible="showConfig">
<template #reference>
<span @click="setMetricConfig(index)">
<Icon class="cp mr-5" iconName="mode_edit" size="middle" />
</span>
</template>
<StandardOptions @update="queryMetrics" @close="showConfig = false" />
</el-popover>
<span <span
v-show="states.isList || states.metricTypes[0] === 'readMetricsValues'" v-show="states.isList || states.metricTypes[0] === 'readMetricsValues'"
> >
@ -101,13 +109,15 @@ import { ElMessage } from "element-plus";
import Icon from "@/components/Icon.vue"; import Icon from "@/components/Icon.vue";
import { useQueryProcessor, useSourceProcessor } from "@/hooks/useProcessor"; import { useQueryProcessor, useSourceProcessor } from "@/hooks/useProcessor";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { DashboardItem } from "@/types/dashboard"; import { DashboardItem, MetricConfigOpt } from "@/types/dashboard";
import StandardOptions from "./StandardOptions.vue";
/*global defineEmits */ /*global defineEmits */
const { t } = useI18n(); const { t } = useI18n();
const emit = defineEmits(["update", "loading", "changeOpt"]); const emit = defineEmits(["update", "loading", "changeOpt"]);
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const { metrics, metricTypes, graph } = dashboardStore.selectedGrid; const { metrics, metricTypes, graph } = dashboardStore.selectedGrid;
const showConfig = ref<boolean>(false);
const states = reactive<{ const states = reactive<{
metrics: string[]; metrics: string[];
metricTypes: string[]; metricTypes: string[];
@ -127,6 +137,13 @@ const states = reactive<{
dashboardName: graph.dashboardName, dashboardName: graph.dashboardName,
dashboardList: [{ label: "", value: "" }], dashboardList: [{ label: "", value: "" }],
}); });
const currentMetricConfig = ref<MetricConfigOpt>({
unit: "",
label: "",
labelsIndex: "",
calculation: "",
sortOrder: "DES",
});
states.isList = ListChartTypes.includes(graph.type); states.isList = ListChartTypes.includes(graph.type);
const defaultLen = ref<number>(states.isList ? 5 : 20); const defaultLen = ref<number>(states.isList ? 5 : 20);
@ -323,8 +340,8 @@ async function queryMetrics() {
if (states.isList) { if (states.isList) {
return; return;
} }
const { standard } = dashboardStore.selectedGrid; const { metricConfig } = dashboardStore.selectedGrid;
const params = useQueryProcessor({ ...states, standard }); const params = useQueryProcessor({ ...states, metricConfig });
if (!params) { if (!params) {
emit("update", {}); emit("update", {});
return; return;
@ -337,7 +354,7 @@ async function queryMetrics() {
ElMessage.error(json.errors); ElMessage.error(json.errors);
return; return;
} }
const source = useSourceProcessor(json, { ...states, standard }); const source = useSourceProcessor(json, { ...states, metricConfig });
emit("update", source); emit("update", source);
} }
@ -393,6 +410,28 @@ function setMetricTypeList(type: string) {
} }
return MetricTypes[type]; return MetricTypes[type];
} }
function setMetricConfig(index: number) {
showConfig.value = true;
const n = {
unit: "",
label: "",
calculation: "",
labelsIndex: "",
sortOrder: "DES",
};
if (
!dashboardStore.selectedGrid.metricConfig ||
!dashboardStore.selectedGrid.metricConfig[index]
) {
currentMetricConfig.value = n;
return;
}
currentMetricConfig.value = {
...n,
...dashboardStore.selectedGrid.metricConfig[index],
};
showConfig.value = true;
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ds-name { .ds-name {

View File

@ -13,174 +13,125 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="item"> <div class="config-panel">
<Icon
class="cp mr-5 close"
iconName="cancel"
size="middle"
@click="closePopper"
/>
<div class="item mb-10">
<span class="label">{{ t("unit") }}</span> <span class="label">{{ t("unit") }}</span>
<el-input <el-input
class="input" class="input"
v-model="selectedGrid.standard.unit" v-model="currentMetric.unit"
size="small" size="small"
placeholder="Please input Unit" placeholder="Please input unit"
@change="changeConfigs(index, { unit: currentMetricConfig.unit })"
/>
</div>
<div class="item mb-10">
<span class="label">{{ t("metricLabel") }}</span>
<el-input
class="input"
v-model="currentMetric.label"
size="small"
placeholder="Please input a name"
@change="changeConfigs(index, { label: currentMetricConfig.label })"
/>
</div>
<div class="item mb-10">
<span class="label">{{ t("labelsIndex") }}</span>
<el-input
class="input"
v-model="currentMetric.labelsIndex"
size="small"
placeholder="auto"
@change="
changeConfigs(index, { label: currentMetricConfig.labelsIndex })
"
/>
</div>
<div class="item mb-10">
<span class="label">{{ t("aggregation") }}</span>
<Selector
:value="currentMetric.calculation"
:options="CalculationOpts"
size="small"
placeholder="Select a option"
@change="changeConfigs(index, { calculation: $event[0].value })"
class="aggregation"
:clearable="true"
/> />
</div> </div>
<div class="item"> <div class="item">
<span class="label">{{ t("sortOrder") }}</span> <span class="label">{{ t("sortOrder") }}</span>
<Selector <Selector
:value="sortOrder" :value="currentMetric.sortOrder || 'DES'"
:options="SortOrder" :options="SortOrder"
size="small" size="small"
placeholder="Select a sort order" placeholder="Select a sort order"
class="selector" class="aggregation"
@change="changeStandardOpt({ sortOrder })" @change="changeConfigs(index, { sortOrder: $event[0].value })"
/> />
</div> </div>
<div class="item">
<span class="label">{{ t("labels") }}</span>
<el-input
class="input"
v-model="selectedGrid.standard.metricLabels"
size="small"
placeholder="auto"
@change="changeStandardOpt"
/>
</div>
<div class="item">
<span class="label">{{ t("labelsIndex") }}</span>
<el-input
class="input"
v-model="selectedGrid.standard.labelsIndex"
size="small"
placeholder="auto"
@change="changeStandardOpt"
/>
</div>
<div class="item">
<span class="label">{{ t("plus") }}</span>
<el-input-number
class="input"
v-model="selectedGrid.standard.plus"
:min="0"
size="small"
placeholder="Please input"
@change="changeStandardOpt"
/>
</div>
<div class="item">
<span class="label">{{ t("minus") }}</span>
<el-input-number
class="input"
v-model="selectedGrid.standard.minus"
:min="0"
size="small"
placeholder="Please input"
@change="changeStandardOpt"
/>
</div>
<div class="item">
<span class="label">{{ t("multiply") }}</span>
<el-input-number
class="input"
v-model="selectedGrid.standard.multiply"
:min="1"
size="small"
placeholder="Please input"
@change="changeStandardOpt"
/>
</div>
<div class="item">
<span class="label">{{ t("divide") }}</span>
<el-input-number
class="input"
v-model="selectedGrid.standard.divide"
size="small"
placeholder="Please input"
:min="1"
@change="changeStandardOpt"
/>
</div>
<div class="item">
<span class="label">{{ t("convertToMilliseconds") }}</span>
<el-input-number
class="input"
:min="0"
v-model="selectedGrid.standard.milliseconds"
size="small"
placeholder="Please input"
@change="changeStandardOpt"
/>
</div>
<div class="item">
<span class="label">{{ t("convertToSeconds") }}</span>
<el-input-number
class="input"
:min="0"
v-model="selectedGrid.standard.seconds"
size="small"
placeholder="Please input"
@change="changeStandardOpt"
/>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from "vue"; import { ref } from "vue";
import type { PropType } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { SortOrder } from "../../data"; import { SortOrder, CalculationOpts } from "../../data";
import { useDashboardStore } from "@/store/modules/dashboard"; import { useDashboardStore } from "@/store/modules/dashboard";
import { useQueryProcessor, useSourceProcessor } from "@/hooks/useProcessor"; import { MetricConfigOpt } from "@/types/dashboard";
import { ElMessage } from "element-plus";
/*global defineEmits */ /*global defineEmits, defineProps */
const props = defineProps({
currentMetricConfig: {
type: Object as PropType<MetricConfigOpt>,
default: () => ({ unit: "" }),
},
index: { type: Number, default: 0 },
});
const { t } = useI18n(); const { t } = useI18n();
const emit = defineEmits(["update", "loading"]); const emit = defineEmits(["update", "close"]);
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const { selectedGrid } = dashboardStore; const currentMetric = ref<MetricConfigOpt>(props.currentMetricConfig);
const sortOrder = ref<string>(selectedGrid.standard.sortOrder || "DES");
function changeStandardOpt(param?: any) { function changeConfigs(index: number, param: { [key: string]: string }) {
let standard = dashboardStore.selectedGrid.standard; const metricConfig = dashboardStore.selectedGrid.metricConfig || [];
if (param) { metricConfig[index] = { ...metricConfig[index], ...param };
standard = { dashboardStore.selectWidget({
...dashboardStore.selectedGrid.standard, ...dashboardStore.selectedGrid,
...param, metricConfig,
}; });
dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, standard }); console.log(dashboardStore.selectedGrid);
} emit("update");
queryMetrics();
} }
async function queryMetrics() {
const params = useQueryProcessor(dashboardStore.selectedGrid);
if (!params) {
emit("update", {});
return;
}
emit("loading", true); function closePopper() {
const json = await dashboardStore.fetchMetricValue(params); emit("close");
emit("loading", false);
if (json.errors) {
ElMessage.error(json.errors);
return;
}
const source = useSourceProcessor(json, dashboardStore.selectedGrid);
emit("update", source);
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.config-panel {
padding: 10px 5px;
position: relative;
}
.label { .label {
font-size: 13px; width: 150px;
font-weight: 500; display: inline-block;
display: block; font-size: 12px;
margin-bottom: 5px;
} }
.input { .close {
width: 500px; position: absolute;
top: -8px;
right: -15px;
} }
.item { .aggregation {
margin-bottom: 10px; width: 365px;
}
.selector {
width: 500px;
} }
</style> </style>

View File

@ -128,7 +128,7 @@ export default defineComponent({
const d = { const d = {
metrics: props.data.metrics, metrics: props.data.metrics,
metricTypes: props.data.metricTypes, metricTypes: props.data.metricTypes,
standard: props.data.standard, metricConfig: props.data.metricConfig || [],
}; };
state.source = useSourceProcessor(json, d); state.source = useSourceProcessor(json, d);
} }

View File

@ -264,3 +264,11 @@ export const TextColors: { [key: string]: string } = {
black: "#000", black: "#000",
orange: "#E6A23C", orange: "#E6A23C",
}; };
export const CalculationOpts = [
{ label: "Percentage", value: "percentage" },
{ label: "ByteToKB", value: "byteToKB" },
{ label: "ConvertMilliseconds", value: "convertMilliseconds" },
{ label: "ConvertSeconds", value: "convertSeconds" },
{ label: "Apdex", value: "apdex" },
];