This commit is contained in:
Fine 2025-02-19 10:32:08 +08:00
parent 6ef063270d
commit 465d8139ea
4 changed files with 36 additions and 40 deletions

View File

@ -13,6 +13,7 @@ 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>
<SelectorLegend :data="option.legend.data" :show="legendSelector" @change="changeLegend" />
<div class="chart" ref="chartRef" :style="`height:${height};width:${width};`"> <div class="chart" ref="chartRef" :style="`height:${height};width:${width};`">
<div v-if="!available" class="no-data">No Data</div> <div v-if="!available" class="no-data">No Data</div>
<div <div
@ -54,6 +55,7 @@ limitations under the License. -->
import Trace from "@/views/dashboard/related/trace/Index.vue"; import Trace from "@/views/dashboard/related/trace/Index.vue";
import associateProcessor from "@/hooks/useAssociateProcessor"; import associateProcessor from "@/hooks/useAssociateProcessor";
import { WidgetType } from "@/views/dashboard/data"; import { WidgetType } from "@/views/dashboard/data";
import SelectorLegend from "./SelectorLegend.vue";
/*global Nullable, defineProps, defineEmits, Indexable*/ /*global Nullable, defineProps, defineEmits, Indexable*/
const emits = defineEmits(["select"]); const emits = defineEmits(["select"]);
@ -84,9 +86,9 @@ limitations under the License. -->
type: Array as PropType<{ widgetId: string }[]>, type: Array as PropType<{ widgetId: string }[]>,
default: () => [], default: () => [],
}, },
legend: { legendSelector: {
type: Array as PropType<string[]>, type: Boolean,
default: () => [], default: false,
}, },
}); });
const available = computed( const available = computed(
@ -208,6 +210,23 @@ limitations under the License. -->
}); });
} }
function changeLegend(names: string[]) {
const instance = getInstance();
for (const item of props.option.legend.data) {
if (names.includes(item.name)) {
instance.dispatchAction({
type: "legendSelect",
name: item.name,
});
} else {
instance.dispatchAction({
type: "legendUnSelect",
name: item.name,
});
}
}
}
watch( watch(
() => props.option, () => props.option,
(newVal, oldVal) => { (newVal, oldVal) => {
@ -232,20 +251,6 @@ limitations under the License. -->
}, },
); );
watch(
() => props.legend,
() => {
const instance = getInstance();
console.log(props.legend);
for (const l of props.legend) {
instance.dispatchAction({
type: "legendSelect",
name: l,
});
}
},
);
onBeforeUnmount(() => { onBeforeUnmount(() => {
removeResizeListener(unref(chartRef), resize); removeResizeListener(unref(chartRef), resize);
}); });

View File

@ -21,39 +21,37 @@ limitations under the License. -->
:options="Options" :options="Options"
@change="changeLegend" @change="changeLegend"
filterable filterable
v-if="config.asSelector" v-if="show"
/> />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref, watch } from "vue"; import { computed, ref, watch } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
import type { Option } from "@/types/app"; import type { Option } from "@/types/app";
import type { LegendOptions } from "@/types/dashboard";
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object as PropType<{ [key: string]: number[] }>, type: Array as PropType<{ name: string }[]>,
default: () => ({}), default: () => [],
}, },
config: { show: {
type: Object as PropType<LegendOptions>, type: Boolean,
default: () => ({}), default: false,
}, },
}); });
const emits = defineEmits(["change"]); const emits = defineEmits(["change"]);
const Options = computed(() => props.data.map((d: { name: string }) => ({ label: d.name, value: d.name })));
const legend = ref<string[]>([]); const legend = ref<string[]>([]);
const Options = computed(() => Object.keys(props.data || {}).map((d: string) => ({ label: d, value: d })));
function changeLegend(opt: Option[]) { function changeLegend(opt: Option[]) {
legend.value = opt.map((d: Option) => d.value); legend.value = opt.map((d: Option) => d.value);
emits("change", legend.value); emits("change", legend.value);
} }
watch( watch(
() => props.data, () => props.data,
() => { () => {
legend.value = Object.keys(props.data || {}).filter( legend.value = props.data.map((d) => d.name);
(i: string) => Array.isArray(props.data[i]) && props.data[i].length,
);
}, },
); );
</script> </script>

View File

@ -50,6 +50,7 @@ declare module 'vue' {
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
Selector: typeof import('./../components/Selector.vue')['default'] Selector: typeof import('./../components/Selector.vue')['default']
SelectorLegend: typeof import('./../components/SelectorLegend.vue')['default']
SelectSingle: typeof import('./../components/SelectSingle.vue')['default'] SelectSingle: typeof import('./../components/SelectSingle.vue')['default']
Tags: typeof import('./../components/Tags.vue')['default'] Tags: typeof import('./../components/Tags.vue')['default']
TimePicker: typeof import('./../components/TimePicker.vue')['default'] TimePicker: typeof import('./../components/TimePicker.vue')['default']

View File

@ -14,13 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="graph flex-v" :class="setRight ? 'flex-h' : 'flex-v'"> <div class="graph flex-v" :class="setRight ? 'flex-h' : 'flex-v'">
<SelectorLegend :config="config.legend" :data="props.data" @change="changeLegend" />
<Graph <Graph
:option="option" :option="option"
:filters="config.filters" :filters="config.filters"
:relatedTrace="config.relatedTrace" :relatedTrace="config.relatedTrace"
:associate="config.associate || []" :associate="config.associate || []"
:legend="legendItems" :legendSelector="legendSelector"
@select="clickEvent" @select="clickEvent"
/> />
<Legend :config="config.legend" :data="data" :intervalTime="intervalTime" /> <Legend :config="config.legend" :data="data" :intervalTime="intervalTime" />
@ -31,7 +30,6 @@ limitations under the License. -->
import type { PropType } from "vue"; import type { PropType } from "vue";
import type { LineConfig, EventParams, RelatedTrace, Filters } from "@/types/dashboard"; import type { LineConfig, EventParams, RelatedTrace, Filters } from "@/types/dashboard";
import Legend from "./components/Legend.vue"; import Legend from "./components/Legend.vue";
import SelectorLegend from "./components/SelectorLegend.vue";
import useLegendProcess from "@/hooks/useLegendProcessor"; import useLegendProcess from "@/hooks/useLegendProcessor";
import { isDef } from "@/utils/is"; import { isDef } from "@/utils/is";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
@ -69,7 +67,7 @@ limitations under the License. -->
}); });
const appStore = useAppStoreWithOut(); const appStore = useAppStoreWithOut();
const setRight = ref<boolean>(false); const setRight = ref<boolean>(false);
const legendItems = ref<string[]>([]); const legendSelector = computed(() => props.config.legend?.asSelector);
const option = computed(() => getOption()); const option = computed(() => getOption());
function getOption() { function getOption() {
const { showEchartsLegend, isRight, chartColors } = useLegendProcess(props.config.legend); const { showEchartsLegend, isRight, chartColors } = useLegendProcess(props.config.legend);
@ -77,8 +75,7 @@ limitations under the License. -->
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,
); );
legendItems.value = keys; const temp = keys.map((i: string) => {
const temp = legendItems.value.map((i: string) => {
const serie: any = { const serie: any = {
data: props.data[i].map((item: number, itemIndex: number) => [props.intervalTime[itemIndex], item]), data: props.data[i].map((item: number, itemIndex: number) => [props.intervalTime[itemIndex], item]),
name: i, name: i,
@ -156,7 +153,7 @@ limitations under the License. -->
top: 0, top: 0,
left: 0, left: 0,
itemWidth: 12, itemWidth: 12,
data: legendItems.value.map((d: string) => ({ name: d })), data: keys.map((d: string) => ({ name: d })),
...legend, ...legend,
}, },
grid: { grid: {
@ -196,11 +193,6 @@ limitations under the License. -->
function clickEvent(params: EventParams) { function clickEvent(params: EventParams) {
emits("click", params); emits("click", params);
} }
function changeLegend(params: string[]) {
legendItems.value = params;
console.log(legendItems.value);
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.graph { .graph {