|
@@ -1,141 +1,172 @@
|
|
|
<template>
|
|
|
<div class="metrics-cards">
|
|
|
<MCard
|
|
|
- v-model="info.metric"
|
|
|
- :metric-items="props.metricItems"
|
|
|
- :color="info.color"
|
|
|
- v-for="info in displayMetrics"
|
|
|
- @change-metric="changedMetric"
|
|
|
- @click="clickCard(info.metric)"/>
|
|
|
+ v-for="info in displayMetrics"
|
|
|
+ :key="info.metric"
|
|
|
+ v-model="info.metric"
|
|
|
+ :color="info.color"
|
|
|
+ :metric-items="props.metricItems"
|
|
|
+ @click="clickCard(info.metric)"
|
|
|
+ @change-metric="changedMetric" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { ref, Ref, onBeforeMount, watch, onMounted, computed } from 'vue'
|
|
|
-import MCard from './mCard.vue'
|
|
|
+import { computed, onBeforeMount, ref, Ref, watch } from 'vue';
|
|
|
+import MCard from './mCard.vue';
|
|
|
import XEUtils from 'xe-utils';
|
|
|
+import { initData, weekInitData } from '/@/views/reportManage/dataCenter/utils/enum';
|
|
|
|
|
|
interface Props {
|
|
|
modelValue: ShowMetric[],
|
|
|
metricItems: MetricData[],
|
|
|
}
|
|
|
-const colorsMap: { [key: string]: boolean } = {}
|
|
|
-const props = defineProps<Props>()
|
|
|
-const emits = defineEmits(['change', 'update:modelValue'])
|
|
|
-// const allMetricItems = ref(props.metricItems)
|
|
|
-const selectedMetric = ref(props.modelValue)
|
|
|
-const displayMetrics: Ref<{metric:string, color?: string}[]> = ref([])
|
|
|
-
|
|
|
-const metricMap = computed(():{[key: string]: string} => {
|
|
|
- const tmp:{[key: string]: string} = {}
|
|
|
+
|
|
|
+const dateType = inject<Ref>('statDim');
|
|
|
+const colorsMap: { [key: string]: boolean } = {};
|
|
|
+const props = defineProps<Props>();
|
|
|
+const emits = defineEmits(['change', 'update:modelValue']);
|
|
|
+const selectedMetric = ref(props.modelValue);
|
|
|
+const displayMetrics: Ref<{ metric: string, color?: string }[]> = ref([]);
|
|
|
+
|
|
|
+const metricMap = computed(() => {
|
|
|
+ const tmp: { [key: string]: string } = {};
|
|
|
for (const info of props.metricItems) {
|
|
|
- tmp[info.value] = info.label
|
|
|
+ tmp[info.value] = info.label;
|
|
|
+ }
|
|
|
+ return tmp;
|
|
|
+});
|
|
|
+
|
|
|
+const initializeMetrics = () => {
|
|
|
+ selectedMetric.value = [];
|
|
|
+ displayMetrics.value = [];
|
|
|
+ //console.log('初始化', selectedMetric.value);
|
|
|
+ Object.keys(colorsMap).forEach(key => delete colorsMap[key]);
|
|
|
+
|
|
|
+ if (dateType.value === 'day' || dateType.value === 'month') {
|
|
|
+ // 不要改成initData,不然会动态变化
|
|
|
+ selectedMetric.value = [{metric: 'sales', color: '#0085ff', label: '销售额'},
|
|
|
+ {metric: 'sales_last_year', color: '#ff9500', label: '上年销售额'},
|
|
|
+ {metric: 'sales_last_month', color: '#3fd4cf', label: '上月销售额'},];
|
|
|
+ } else if (dateType.value === 'week') {
|
|
|
+ selectedMetric.value = weekInitData.value;
|
|
|
}
|
|
|
- return tmp
|
|
|
-})
|
|
|
-onBeforeMount(()=> {
|
|
|
- const dup:{[key: string]: boolean} = {}
|
|
|
- // 初始显示图线的三个维度
|
|
|
+ console.log('initData.value', initData);
|
|
|
+ console.log('111', selectedMetric.value);
|
|
|
for (const info of selectedMetric.value) {
|
|
|
- displayMetrics.value.push({ metric: info.metric, color: info.color })
|
|
|
- dup[info.metric] = true
|
|
|
- if (info.color) { colorsMap[info.color] = true }
|
|
|
+ displayMetrics.value.push({metric: info.metric, color: info.color});
|
|
|
+ if (info.color) {
|
|
|
+ colorsMap[info.color] = true;
|
|
|
+ }
|
|
|
}
|
|
|
-})
|
|
|
+ console.log('initializeMetrics', selectedMetric.value);
|
|
|
+ emits('update:modelValue', selectedMetric.value);
|
|
|
+};
|
|
|
+
|
|
|
+onBeforeMount(initializeMetrics);
|
|
|
+
|
|
|
+watch(dateType, initializeMetrics);
|
|
|
|
|
|
const getColor = () => {
|
|
|
- for (const [k,v] of Object.entries(colorsMap)) {
|
|
|
+ for (const [k, v] of Object.entries(colorsMap)) {
|
|
|
if (!v) {
|
|
|
- colorsMap[k] = true
|
|
|
- return k
|
|
|
+ colorsMap[k] = true;
|
|
|
+ return k;
|
|
|
}
|
|
|
}
|
|
|
- return ""
|
|
|
-}
|
|
|
-const unsetColor = (color: string ) => {
|
|
|
+ return '';
|
|
|
+};
|
|
|
+const unsetColor = (color: string) => {
|
|
|
if (XEUtils.has(colorsMap, color)) {
|
|
|
- colorsMap[color] = false
|
|
|
+ colorsMap[color] = false;
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
+
|
|
|
const changedMetric = (newVal: string, oldVal: string) => {
|
|
|
for (const info of props.metricItems) {
|
|
|
if (info.value === newVal) {
|
|
|
- info.disabled = true
|
|
|
+ info.disabled = true;
|
|
|
} else if (info.value === oldVal) {
|
|
|
- info.disabled = false
|
|
|
+ info.disabled = false;
|
|
|
}
|
|
|
}
|
|
|
- const index = selectedMetric.value.findIndex( info => info.metric === oldVal)
|
|
|
+ const index = selectedMetric.value.findIndex(info => info.metric === oldVal);
|
|
|
if (index > -1) {
|
|
|
- selectedMetric.value[index].metric = newVal
|
|
|
- selectedMetric.value[index].label = metricMap.value[newVal]
|
|
|
- emits('update:modelValue', selectedMetric.value)
|
|
|
- emits('change', selectedMetric.value)
|
|
|
+ selectedMetric.value[index].metric = newVal;
|
|
|
+ selectedMetric.value[index].label = metricMap.value[newVal];
|
|
|
+ emits('update:modelValue', selectedMetric.value);
|
|
|
+ emits('change', selectedMetric.value);
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
+
|
|
|
const clickCard = (metric: string) => {
|
|
|
- const index = selectedMetric.value.findIndex( info => info.metric === metric)
|
|
|
+ const index = selectedMetric.value.findIndex(info => info.metric === metric);
|
|
|
if (index > -1) { // 已存在则删除
|
|
|
- if (selectedMetric.value.length <= 1 ) return
|
|
|
- const tmp = selectedMetric.value[index]
|
|
|
- selectedMetric.value.splice(index, 1)
|
|
|
- unsetColor(tmp.color)
|
|
|
- emits('update:modelValue', selectedMetric.value)
|
|
|
- emits('change', selectedMetric.value)
|
|
|
+ if (selectedMetric.value.length <= 1) return;
|
|
|
+ const tmp = selectedMetric.value[index];
|
|
|
+ selectedMetric.value.splice(index, 1);
|
|
|
+ unsetColor(tmp.color);
|
|
|
+ emits('update:modelValue', selectedMetric.value);
|
|
|
+ emits('change', selectedMetric.value);
|
|
|
} else { // 不存在则添加
|
|
|
- if (selectedMetric.value.length === 3) {
|
|
|
- selectedMetric.value[2].metric = metric
|
|
|
- selectedMetric.value[2].label = metricMap.value[metric]
|
|
|
+ if (selectedMetric.value.length === 3) {
|
|
|
+ selectedMetric.value[2].metric = metric;
|
|
|
+ selectedMetric.value[2].label = metricMap.value[metric];
|
|
|
} else {
|
|
|
- const color = getColor()
|
|
|
- selectedMetric.value.push({ metric: metric, color: color, label: metricMap.value[metric]})
|
|
|
+ const color = getColor();
|
|
|
+ selectedMetric.value.push({metric: metric, color: color, label: metricMap.value[metric]});
|
|
|
}
|
|
|
- emits('update:modelValue', selectedMetric.value)
|
|
|
- emits('change', selectedMetric.value)
|
|
|
}
|
|
|
-}
|
|
|
-watch(selectedMetric.value, () => {
|
|
|
- const cache:{ [key: string]: string } = {}
|
|
|
+
|
|
|
+ emits('update:modelValue', selectedMetric.value);
|
|
|
+ emits('change', selectedMetric.value);
|
|
|
+};
|
|
|
+
|
|
|
+watch(selectedMetric, () => {
|
|
|
+ const cache: { [key: string]: string } = {};
|
|
|
for (const info of selectedMetric.value) {
|
|
|
- cache[info.metric] = info.color
|
|
|
+ cache[info.metric] = info.color;
|
|
|
}
|
|
|
for (const info of displayMetrics.value) {
|
|
|
- const color = cache[info.metric]
|
|
|
+ const color = cache[info.metric];
|
|
|
if (color) {
|
|
|
- info.color = color
|
|
|
+ info.color = color;
|
|
|
} else {
|
|
|
- info.color = undefined
|
|
|
+ info.color = undefined;
|
|
|
}
|
|
|
}
|
|
|
-})
|
|
|
+ console.log('watch', selectedMetric.value);
|
|
|
+}, {deep: true});
|
|
|
|
|
|
watch(
|
|
|
- props.metricItems,
|
|
|
- () => {
|
|
|
- const dup:{[key: string]: boolean} = {}
|
|
|
- for (const info of displayMetrics.value) { dup[info.metric] = true }
|
|
|
- let needNum = 6 - displayMetrics.value.length
|
|
|
- if (needNum > 0) {
|
|
|
- // 从所有维度中选择剩余
|
|
|
+ props.metricItems,
|
|
|
+ () => {
|
|
|
+ const dup: { [key: string]: boolean } = {};
|
|
|
+ for (const info of displayMetrics.value) {
|
|
|
+ dup[info.metric] = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ let needNum = 6 - displayMetrics.value.length;
|
|
|
+ if (needNum > 0) {
|
|
|
+ for (const info of props.metricItems) {
|
|
|
+ if (!dup[info.value]) {
|
|
|
+ displayMetrics.value.push({metric: info.value});
|
|
|
+ dup[info.value] = true;
|
|
|
+ needNum--;
|
|
|
+ if (needNum === 0) break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
for (const info of props.metricItems) {
|
|
|
- if (!dup[info.value]) {
|
|
|
- displayMetrics.value.push({ metric: info.value })
|
|
|
- dup[info.value] = true
|
|
|
- needNum --
|
|
|
- if (needNum === 0) break
|
|
|
+ if (dup[info.value]) {
|
|
|
+ info.disabled = true;
|
|
|
+ } else {
|
|
|
+ info.disabled = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- for (const info of props.metricItems) {
|
|
|
- if (dup[info.value]) {
|
|
|
- info.disabled = true
|
|
|
- } else {
|
|
|
- info.disabled = false
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-)
|
|
|
-
|
|
|
+);
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
@@ -146,4 +177,4 @@ watch(
|
|
|
gap: 12px;
|
|
|
width: 100%;
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|