mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-02 14:34:46 +00:00
feat: support ranges for Value Mappings (#421)
This commit is contained in:
parent
bddbe40974
commit
b6522f4555
@ -386,6 +386,7 @@ const msg = {
|
|||||||
tabExpressions: "Tab Expressions",
|
tabExpressions: "Tab Expressions",
|
||||||
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
||||||
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
||||||
contentDecorations: "Content Decorations",
|
valueMappings: "Value Mappings",
|
||||||
|
mappingTip: "Notice: The mapping key is a Regex string, for instance, ^-?(0|[1-9][0-9]*|2)(\\.0+)?$",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
@ -386,6 +386,7 @@ const msg = {
|
|||||||
tabExpressions: "Tab Expressions",
|
tabExpressions: "Tab Expressions",
|
||||||
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
|
||||||
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
|
||||||
contentDecorations: "Content Decorations",
|
valueMappings: "Value Mappings",
|
||||||
|
mappingTip: "Notice: The mapping key is a Regex string, for instance, ^-?(0|[1-9][0-9]*|2)(\\.0+)?$",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
@ -384,6 +384,7 @@ const msg = {
|
|||||||
tabExpressions: "Tab表达式",
|
tabExpressions: "Tab表达式",
|
||||||
hierarchyNodeMetrics: "层次图节点的指标",
|
hierarchyNodeMetrics: "层次图节点的指标",
|
||||||
hierarchyNodeDashboard: "作为层次图节点的dashboard",
|
hierarchyNodeDashboard: "作为层次图节点的dashboard",
|
||||||
contentDecorations: "内容装饰",
|
valueMappings: "值映射",
|
||||||
|
mappingTip: "注意: 映射键是一个正则表达式字符串,比如 ^-?(0|[1-9][0-9]*|2)(\\.0+)?$",
|
||||||
};
|
};
|
||||||
export default msg;
|
export default msg;
|
||||||
|
2
src/types/dashboard.d.ts
vendored
2
src/types/dashboard.d.ts
vendored
@ -123,7 +123,7 @@ export interface CardConfig {
|
|||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
showUnit?: boolean;
|
showUnit?: boolean;
|
||||||
textAlign?: "center" | "right" | "left";
|
textAlign?: "center" | "right" | "left";
|
||||||
decorations?: { [key: string]: string };
|
valueMappings?: { [key: string]: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TextConfig {
|
export interface TextConfig {
|
||||||
|
@ -32,7 +32,7 @@ limitations under the License. -->
|
|||||||
:config="{
|
:config="{
|
||||||
i: 0,
|
i: 0,
|
||||||
...graph,
|
...graph,
|
||||||
decorations: graph?.decorations,
|
valueMappings: graph?.valueMappings,
|
||||||
metricConfig: config.metricConfig,
|
metricConfig: config.metricConfig,
|
||||||
expressions: config.expressions || [],
|
expressions: config.expressions || [],
|
||||||
typesOfMQE: typesOfMQE || [],
|
typesOfMQE: typesOfMQE || [],
|
||||||
|
@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License. -->
|
limitations under the License. -->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<span class="label">{{ t("contentDecorations") }}</span>
|
<value-mappings />
|
||||||
<content-decorations />
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="label">{{ t("fontSize") }}</span>
|
<span class="label">{{ t("fontSize") }}</span>
|
||||||
@ -39,7 +38,7 @@ limitations under the License. -->
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import ContentDecorations from "./components/ContentDecorations.vue";
|
import ValueMappings from "./components/ValueMappings.vue";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
|
@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License. -->
|
limitations under the License. -->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<span class="label">{{ t("contentDecorations") }}</span>
|
<value-mappings />
|
||||||
<content-decorations />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<span class="label">{{ t("showValues") }}</span>
|
<span class="label">{{ t("showValues") }}</span>
|
||||||
@ -41,7 +40,7 @@ limitations under the License. -->
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import ContentDecorations from "./components/ContentDecorations.vue";
|
import ValueMappings from "./components/ValueMappings.vue";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
|
@ -13,13 +13,17 @@ 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>
|
||||||
|
<span class="label">{{ t("valueMappings") }}</span>
|
||||||
|
<span class="label red">({{ t("mappingTip") }})</span>
|
||||||
|
</div>
|
||||||
<div v-for="(key, index) in keys" :key="index" class="mb-10 flex-h">
|
<div v-for="(key, index) in keys" :key="index" class="mb-10 flex-h">
|
||||||
<div class="content-decoration" contenteditable="true" @blur="changeKeys($event, index)">
|
<div class="content-decoration" contenteditable="true" @blur="changeKeys($event, index)">
|
||||||
{{ key }}
|
{{ key }}
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-5 mr-10">:</div>
|
<div class="ml-5 mr-10">:</div>
|
||||||
<div class="content-decoration" contenteditable="true" @blur="changeValues($event, key)">
|
<div class="content-decoration" contenteditable="true" @blur="changeValues($event, key)">
|
||||||
{{ decorations[key] }}
|
{{ valueMappings[key] }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="index === keys.length - 1">
|
<div v-if="index === keys.length - 1">
|
||||||
<Icon class="cp mr-5" iconName="add_circle_outlinecontrol_point" size="middle" @click="addDecoration" />
|
<Icon class="cp mr-5" iconName="add_circle_outlinecontrol_point" size="middle" @click="addDecoration" />
|
||||||
@ -36,26 +40,28 @@ limitations under the License. -->
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const graph = dashboardStore.selectedGrid.graph;
|
const graph = dashboardStore.selectedGrid.graph;
|
||||||
const decorations = ref<{ [key: string]: string }>(graph?.decorations || {});
|
const valueMappings = ref<{ [key: string]: string }>(graph?.valueMappings || {});
|
||||||
const keys = ref<string[]>(graph.decorations ? Object.keys(decorations.value) : [""]);
|
const keys = ref<string[]>(graph.valueMappings ? Object.keys(valueMappings.value) : [""]);
|
||||||
|
|
||||||
function changeKeys(event: any, index: number) {
|
function changeKeys(event: any, index: number) {
|
||||||
const params = event.target.textContent || "";
|
const params = event.target.textContent || "";
|
||||||
const list = Object.keys(decorations.value);
|
const list = Object.keys(valueMappings.value);
|
||||||
if (params) {
|
if (params) {
|
||||||
decorations.value[params] = decorations.value[list[index]];
|
valueMappings.value[params] = valueMappings.value[list[index]];
|
||||||
}
|
}
|
||||||
delete decorations.value[list[index]];
|
delete valueMappings.value[list[index]];
|
||||||
keys.value = Object.keys(decorations.value);
|
keys.value = Object.keys(valueMappings.value);
|
||||||
updateConfig({ decorations: decorations.value });
|
updateConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeValues(event: any, key: string) {
|
function changeValues(event: any, key: string) {
|
||||||
decorations.value[key] = event.target.textContent || "";
|
valueMappings.value[key] = event.target.textContent || "";
|
||||||
updateConfig({ decorations: decorations.value });
|
updateConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addDecoration() {
|
function addDecoration() {
|
||||||
@ -66,18 +72,15 @@ limitations under the License. -->
|
|||||||
if (!keys.value.length) {
|
if (!keys.value.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!keys.value[index]) {
|
delete valueMappings.value[keys.value[index]];
|
||||||
return;
|
|
||||||
}
|
|
||||||
delete decorations.value[keys.value[index]];
|
|
||||||
keys.value.splice(index, 1);
|
keys.value.splice(index, 1);
|
||||||
updateConfig({ decorations: decorations.value });
|
updateConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateConfig(param: { [key: string]: unknown }) {
|
function updateConfig() {
|
||||||
const graph = {
|
const graph = {
|
||||||
...dashboardStore.selectedGrid.graph,
|
...dashboardStore.selectedGrid.graph,
|
||||||
...param,
|
valueMappings: valueMappings.value,
|
||||||
};
|
};
|
||||||
dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, graph });
|
dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, graph });
|
||||||
}
|
}
|
||||||
@ -97,4 +100,10 @@ limitations under the License. -->
|
|||||||
border-color: $active-color;
|
border-color: $active-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -22,7 +22,7 @@ limitations under the License. -->
|
|||||||
justifyContent: config.textAlign || 'center',
|
justifyContent: config.textAlign || 'center',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ decorations[singleVal] || singleVal }}
|
{{ getValue() }}
|
||||||
<span class="unit" v-show="config.showUnit && unit">
|
<span class="unit" v-show="config.showUnit && unit">
|
||||||
{{ decodeURIComponent(unit) }}
|
{{ decodeURIComponent(unit) }}
|
||||||
</span>
|
</span>
|
||||||
@ -48,18 +48,31 @@ limitations under the License. -->
|
|||||||
showUnit: true,
|
showUnit: true,
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
metricConfig: [],
|
metricConfig: [],
|
||||||
decorations: {},
|
valueMappings: {},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const metricConfig = computed(() => props.config.metricConfig || []);
|
const metricConfig = computed(() => props.config.metricConfig || []);
|
||||||
const decorations = computed(() => props.config.decorations || {});
|
const valueMappings = computed(() => props.config.valueMappings || {});
|
||||||
const key = computed(() => Object.keys(props.data)[0]);
|
const key = computed(() => Object.keys(props.data)[0]);
|
||||||
const singleVal = computed(() =>
|
const singleVal = computed(() =>
|
||||||
Array.isArray(props.data[key.value]) ? props.data[key.value][0] : props.data[key.value],
|
Array.isArray(props.data[key.value]) ? props.data[key.value][0] : props.data[key.value],
|
||||||
);
|
);
|
||||||
const unit = computed(() => metricConfig.value[0] && encodeURIComponent(metricConfig.value[0].unit || ""));
|
const unit = computed(() => metricConfig.value[0] && encodeURIComponent(metricConfig.value[0].unit || ""));
|
||||||
|
|
||||||
|
function getValue() {
|
||||||
|
if (valueMappings.value[singleVal.value]) {
|
||||||
|
return valueMappings.value[singleVal.value];
|
||||||
|
}
|
||||||
|
const list = Object.keys(valueMappings.value);
|
||||||
|
for (const i of list) {
|
||||||
|
if (new RegExp(i).test(String(singleVal.value))) {
|
||||||
|
return valueMappings.value[i] || singleVal.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return singleVal.value;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.chart-card {
|
.chart-card {
|
||||||
|
@ -58,14 +58,14 @@ limitations under the License. -->
|
|||||||
showTableValues: boolean;
|
showTableValues: boolean;
|
||||||
tableHeaderCol2: string;
|
tableHeaderCol2: string;
|
||||||
typesOfMQE: string[];
|
typesOfMQE: string[];
|
||||||
decorations: {};
|
valueMappings: {};
|
||||||
}>,
|
}>,
|
||||||
default: () => ({ showTableValues: true }),
|
default: () => ({ showTableValues: true }),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const decorations = computed<{ [key: number]: string }>(() => props.config.decorations || {});
|
const valueMappings = computed<{ [key: string]: string }>(() => props.config.valueMappings || {});
|
||||||
const nameWidth = computed(() => (props.config.showTableValues ? 80 : 100));
|
const nameWidth = computed(() => (props.config.showTableValues ? 80 : 100));
|
||||||
const dataKeys = computed(() => {
|
const dataKeys = computed(() => {
|
||||||
const keys = Object.keys(props.data || {}).filter(
|
const keys = Object.keys(props.data || {}).filter(
|
||||||
@ -75,9 +75,19 @@ limitations under the License. -->
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
});
|
});
|
||||||
|
|
||||||
function getColValue(keys: string[]) {
|
function getColValue(keys: string[]) {
|
||||||
const val = props.data[(keys as string[]).join(",")][props.data[(keys as string[]).join(",")].length - 1 || 0];
|
const source = props.data[(keys as string[]).join(",")][props.data[(keys as string[]).join(",")].length - 1 || 0];
|
||||||
return decorations.value[val] || val;
|
if (valueMappings.value[source]) {
|
||||||
|
return valueMappings.value[source];
|
||||||
|
}
|
||||||
|
const list = Object.keys(valueMappings.value);
|
||||||
|
for (const i of list) {
|
||||||
|
if (new RegExp(i).test(String(source))) {
|
||||||
|
return valueMappings.value[i] || source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return source;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
Loading…
Reference in New Issue
Block a user