From ca5d73c3932e6b801f098bd615621d4543651cfe Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期四, 24 十月 2024 14:04:31 +0800 Subject: [PATCH] 图表不显示 --- src/components/chat/chatComponents/summaryCom/components/recordSet/RecordSet.vue | 417 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 328 insertions(+), 89 deletions(-) diff --git a/src/components/chat/chatComponents/summaryCom/components/recordSet/RecordSet.vue b/src/components/chat/chatComponents/summaryCom/components/recordSet/RecordSet.vue index 022707c..e16eb87 100644 --- a/src/components/chat/chatComponents/summaryCom/components/recordSet/RecordSet.vue +++ b/src/components/chat/chatComponents/summaryCom/components/recordSet/RecordSet.vue @@ -1,12 +1,12 @@ <!-- 鏄ㄦ棩渚涙按绠$綉姒傚喌 --> <template> - <div class="w-full"> - <div class="flex mb-4 flex-wrap"> + <div class="w-full flex-column"> + <div class="flex mb-4 flex-wrap flex-0"> <!-- TimeRange v-model 璺� @change 涓殑鍊间細涓嶄竴鏍凤紝浠change 涓负鍑� --> - <template v-if="visibleParams && visibleParams.length > 0"> + <template v-if="visibleParams && visibleParams.length > 0 && showFilter"> <component - class="flex-0 m-1" - v-model="paramsValueList[index].value" + class="flex-0 m-2" + v-model="visibleParams[index].value" v-for="(item, index) in visibleParams as any" :key="item.id" :id="item.id" @@ -18,11 +18,36 @@ ></component> </template> <slot> </slot> + <YRange @input="yRangeInput" /> + <el-tooltip + v-if="originChartType === ChartTypeEnum.Score" + :content="`${Object.keys(scoreMap) + .map((key) => `${key} 琛ㄧず${scoreMap[key]}`) + .join(', ')}`" + placement="top-start" + > + <SvgIcon name="fa fa-question-circle-o" :size="15" class="ml-1 cursor-help flex-center" color="#909399" /> + </el-tooltip> - <YRange v-model="yRange" @input="yRangeInput" /> - <el-checkbox class="m-1" v-model="isMultiCompare" label="澶氭棩瀵规瘮" @change="multiCompareChange"></el-checkbox> + <el-checkbox class="m-2" v-model="isMultiCompare" label="澶氭棩瀵规瘮" @change="multiCompareChange"></el-checkbox> + + <DisplayMode class="ml-auto" v-model="showMode" @change="displayModeChange" /> </div> - <div :style="{ height: chartHeight }" v-resize="chartContainerResize" v-loading="chartLoading"> + + <RecordSetTable + :data="tableData" + v-if="tableIsShow" + :key="tableKey" + :tableLimitHeight="tableLimitHeight" + :class="{ 'flex-auto': chartHeight == undefined }" + /> + <div + v-show="!tableIsShow" + :style="{ height: chartHeight }" + :class="{ 'flex-auto': chartHeight == undefined }" + v-resize="chartContainerResize" + v-loading="chartLoading" + > <div ref="chartRef"></div> </div> </div> @@ -33,28 +58,33 @@ import _ from 'lodash'; import moment from 'moment'; import type { PropType } from 'vue'; -import { computed, ref } from 'vue'; +import { computed, ref, shallowRef, watch } from 'vue'; import { SCATTER_SYMBOL_SIZE, getChatChartOption } from '../../../common'; import { useDrawChatChart } from '../../../hooks/useDrawChatChart'; import { ChartTypeEnum } from '../../../types'; +import RecordSetTable from '../recordSetTable/RecordSetTable.vue'; +import DisplayMode from './components/DisplayMode.vue'; import YRange from './components/YRange.vue'; -import type { RecordSet, RecordSetParamsItem } from './types'; +import { DisplayModeType } from './components/types'; +import type { RecordSetParamsItem } from './types'; import { RecordSetParamsType, recordSetMapCom, scoreMap } from './types'; -import { filterQuery } from '/@/api/ai/chat'; +import { curveQuery } from '/@/api/ai/chat'; +import { axisLabelFormatter } from '/@/utils/chart'; import { deepClone } from '/@/utils/other'; import { debounce } from '/@/utils/util'; -import { axisLabelFormatter } from '/@/utils/chart'; - +import { IS_DAY_LIST } from './components/constants'; const chartRef = ref<HTMLDivElement>(null); -const yRange = ref({ - min: null as number, - max: null as number, -}); + +const showMode = ref(DisplayModeType.Chart); // const props = defineProps({ // data: { // type: Object as PropType<RecordSet>, // }, // }); + +const emits = defineEmits<{ + (event: 'updateQuery', res: any): void; +}>(); const props = defineProps({ data: { @@ -68,45 +98,99 @@ }, chartHeight: { type: String, - default: '20rem', + required: false, + }, + showFilter: { + type: Boolean, + default: true, }, }) as { - data: RecordSet; + data: any; + summaryIndex: number; + showFilter: Boolean; }; + +const tableLimitHeight = props.chartHeight == undefined ? undefined : document.body.clientHeight * 0.7; + const chartLoading = ref(false); -const visibleParams = computed(() => { - const visibleList = props.data?.params?.filter((item) => !item?.hide) ?? []; +const stepOptions = [ + { title: '5鍒嗛挓', value: '5 minutes' }, + { title: '10鍒嗛挓', value: '10 minutes' }, + { title: '鍗婂皬鏃�', value: '30 minutes' }, + { title: '1灏忔椂', value: '1 hours' }, + { title: '1澶�', value: '1 days' }, +]; +const getVisibleParams = (data) => { + // const visibleList = props.data?.params?.filter((item) => !item?.hide) ?? []; + // index 浣滀负 id + const visibleList = (data?.filter ?? []).map((item, index) => { + // 涓嶄慨鏀瑰師濮嬪湴鍧� + item.id = index + ''; + + return item; + }); const newList: RecordSetParamsItem[] = []; - let nextMatchIndex = null; for (let index = 0; index < visibleList.length; index++) { - if (nextMatchIndex === index) continue; const current = visibleList[index]; - const currentAny = current as any; - if (index !== visibleList.length - 1 && currentAny.type === RecordSetParamsType.StartTime) { - const next = visibleList[index + 1]; - const nextAny = next as any; - - if (nextAny.group === currentAny.group && nextAny.type === RecordSetParamsType.EndTime) { + switch (current.type) { + case RecordSetParamsType.TimeRange: newList.push({ + id: current.id, type: RecordSetParamsType.TimeRange, - value: [currentAny.value, nextAny.value], - group: currentAny.group, - range: [currentAny, nextAny], - } as any); - nextMatchIndex = index + 1; - } else { - newList.push(current); - } - } else { - newList.push(current); + origin: current, + value: [current.start_value, current.end_value], + title: current.title, + }); + break; + case RecordSetParamsType.Step: + newList.push({ + id: current.id, + type: RecordSetParamsType.Step, + origin: current, + value: current.step_value, + list: stepOptions, + title: current.title, + }); + break; + default: + break; } + Reflect.deleteProperty(current, 'id'); } return newList; -}); -const paramsValueList = ref(deepClone(visibleParams.value)); +}; + +// 鏇存敼 value 鍊硷紝瀹屽叏瑕嗙洊浼氫涪澶卞搷搴旀�э紝鍙慨鏀� value +const updateVisibleParams = (data) => { + const filter = data?.filter ?? []; + + filter.map((newItem, index) => { + const currentItem = visibleParams.value.find((item) => item.id === index + ''); + + if (currentItem) { + if (newItem.type === RecordSetParamsType.TimeRange) { + currentItem.value = [newItem.start_value, newItem.end_value]; + } else { + currentItem.value = newItem.step_value; + } + } + }); +}; + +const visibleParams = ref(getVisibleParams(props.data)); + +const checkIsDayTime = () => { + if (!props.showFilter) return false; + const stepFilter = visibleParams.value.find((item) => item.type === RecordSetParamsType.Step); + if (!stepFilter.origin.step_value) return false; + + return IS_DAY_LIST.includes(stepFilter.origin.step_value); +}; +// 璺ㄥ害鏄惁鏄棩鏈熷舰寮� +// const isDayTime = checkIsDayTime(); let groupedValues = null; let timeIndex = undefined; let valueIndex = undefined; @@ -117,9 +201,11 @@ let preData = null; - let activeChartType: ChartTypeEnum = props.data?.chart_type ?? ChartTypeEnum.Line; -const originChartType = activeChartType; +let originChartType = activeChartType; + +// 缁欒〃鏍肩敤鐨� series +const currentSeries = shallowRef<any[]>(null); const getChartTypeSeriesOption = (type: ChartTypeEnum) => { let result = {}; @@ -175,15 +261,16 @@ }; }); } + currentSeries.value = series; const yAxisFormatter = - originChartType === ChartTypeEnum.Score + originChartType === ChartTypeEnum.Score ? (value) => { return scoreMap[value]; } : axisLabelFormatter; const tooltipValueFormatter = - originChartType === ChartTypeEnum.Score + originChartType === ChartTypeEnum.Score ? (value) => { return scoreMap[value]; } @@ -273,8 +360,7 @@ }); }; -const handleData = () => { - const data = props.data; +const handleData = (data = props.data) => { if (!data || !data.cols || !data.values) { return; } @@ -316,8 +402,7 @@ } }; -const drawChart = () => { - const data = props.data; +const drawChart = (data = props.data) => { if (!data || !data.cols || !data.values) { return; } @@ -326,58 +411,108 @@ }; const { chartContainerResize, chartInstance } = useDrawChatChart({ chartRef, drawChart }); -// 鏇存崲鍒楄〃 -const changeMap = new Map<string, string>(null); +const updateCurrent = (res, isNew = false) => { + const title = res?.title; + const values = res?.values ?? []; + //#region ====================== 鍒锋柊褰撳墠 filter ====================== + // 鍙洿鏂� value锛屼笉鐩存帴瑕嗙洊锛岄槻姝涪澶卞搷搴旀�� + // updateVisibleParams(res); + //#endregion + groupedValues = _.groupBy(values, (item) => item[nameIndex]); + if (isMultiCompare.value) { + handleMultiCompare(); + } else { + if (isNew) { + setNewOption(); + } else { + (currentSeries.value = + groupedValues && + Object.keys(groupedValues).map((item, index) => { + const values = groupedValues[item]; + return { + name: item === 'default' ? '' : item, + data: values.map((item) => [item[timeIndex], item[valueIndex]]), + }; + })), + chartInstance.value?.setOption({ + title: { + text: title, + }, + series: currentSeries.value, + }); + } + } +}; const handleQueryChange = async (val: any, item: RecordSetParamsItem) => { if (!val) return; - const historyId = (props as any).originData.historyId; - const summaryIndex = (props as any).summaryIndex; + const curAgentKey = props.data.agent_key; let res = null; + // 鏀瑰彉鍘熷鍊� + if (item.type === RecordSetParamsType.TimeRange) { + item.origin.start_value = val[0]; + item.origin.end_value = val[1]; + } else { + item.origin.step_value = val; + } try { - if (item.type === RecordSetParamsType.TimeRange) { - changeMap.set(item.range[0].id, val[0]), changeMap.set(item.range[1].id, val[1]); - } else { - changeMap.set(item.id, val); - } - const paramsObj = {}; - for (const [key, value] of changeMap) { - paramsObj[key] = value; - } + // 鐩稿悓 agent_key 涓嬫墍鏈� filter 璇锋眰鍙傛暟 + const filterList = ((props as any).originData?.content?.origin?.summary ?? []).reduce((preVal, curVal) => { + if (curVal.agent_key !== curAgentKey) return preVal; + + const filter = (curVal.filter ?? []).reduce((subPreVal, subCurVal) => { + if (subCurVal.type === RecordSetParamsType.TimeRange) { + subPreVal.push( + ...[ + { + update: subCurVal.update, + value: subCurVal.start_value, + path: subCurVal.start_path, + }, + { + update: subCurVal.update, + value: subCurVal.end_value, + path: subCurVal.end_path, + }, + ] + ); + } else { + subPreVal.push({ + update: subCurVal.update, + value: subCurVal.step_value, + path: subCurVal.step_path, + }); + } + + return subPreVal; + }, []); + + preVal = preVal.concat(filter); + + return preVal; + }, []); const params = { history_id: historyId, - query_index: summaryIndex, - param_json: JSON.stringify(paramsObj), + // 鏌ヨ鍓嶅悗 agent_key 涓嶄細鍙� + agent_key: props.data.agent_key, + filter_json: JSON.stringify(filterList), }; - res = await filterQuery(params); + res = await curveQuery(params); chartLoading.value = true; } finally { chartLoading.value = false; } - const title = res?.values?.title; - const values = res?.values?.values ?? []; - groupedValues = _.groupBy(values, (item) => item[nameIndex]); + emits('updateQuery', res); - if (isMultiCompare.value) { - handleMultiCompare(); - } else { - chartInstance.value.setOption({ - title: { - text: title, - }, - series: - groupedValues && - Object.keys(groupedValues).map((item) => { - const values = groupedValues[item]; - return { - data: values.map((item) => [item[timeIndex], item[valueIndex]]), - }; - }), - }); - } + return; +}; + +let realRange = { + min: null, + max: null, }; const getSingleDayOption = (day = COMMON_DAY) => @@ -429,12 +564,12 @@ } as echarts.EChartsOption); //#region ====================== 璁剧疆Y鑼冨洿 ====================== const debounceSetYRange = debounce((val) => { + (realRange.min = val.min), (realRange.max = val.max); chartInstance.value.setOption({ - yAxis: { - min: val.min, - max: val.max, - }, + yAxis: realRange, }); + + currentSeries.value = currentSeries.value.concat([]); }); const yRangeInput = (val) => { @@ -487,12 +622,116 @@ } }; //#endregion +//#region ====================== 鍒囨崲鏄剧ず妯″紡 ====================== + +const tableIsShow = ref(false); +const displayModeChange = (val: DisplayModeType) => { + if (val === DisplayModeType.List) { + tableIsShow.value = true; + } else { + tableIsShow.value = false; + } +}; + +const tableData = computed(() => { + if (!currentSeries.value) return []; + const min = realRange.min == null ? -Infinity : realRange.min; + const max = realRange.max == null ? Infinity : realRange.max; + const timeDataMap = currentSeries.value.reduce((preVal, curVal, index) => { + for (const item of curVal.data) { + let [time, value] = item; + // 澶氭棩瀵规瘮锛屽彧鏄剧ず鏃跺垎绉� + if (isMultiCompare.value) { + time = time.slice(11); + } + if (value < min || value > max) { + continue; + } + if (!preVal[time]) { + preVal[time] = []; + } + + // score 绫诲瀷锛寁alue 鍊硷紝闇�瑕佹槧灏勬垚鍙︿竴涓�� + if (originChartType === ChartTypeEnum.Score) { + value = scoreMap[value]; + } + preVal[time][index] = value; + } + + return preVal; + }, {}); + + const data = Object.keys(timeDataMap).map((item) => [item, ...timeDataMap[item]]); + const cols = currentSeries.value.map((item, index) => ({ + title: item.name ?? `鍊�${index + 1}`, + type: 'text', + })); + cols.unshift({ + title: '鏃堕棿', + type: 'time', + }); + const result = { + type: 'recordset', + chart: 'table', + title: props.data?.title, + max_cols: 5, + cols: cols, + values: data, + }; + + return result; +}); +//#endregion + +const tableKey = ref('-999'); +watch( + () => currentSeries.value, + (val) => { + tableKey.value = _.random(0, 100000) + ''; + } +); + +const updateAll = (triggerIndex, res) => { + // 褰撳墠 agent_key + const curAgentKey = props.data.agent_key; + const triggerAgentKey = (props as any).originData?.content?.origin?.summary?.[triggerIndex]?.agent_key; + if (curAgentKey !== triggerAgentKey) { + return; + } + if (!curAgentKey) { + return; + } + + // 褰撳墠椤规墍鍦ㄧ储寮� + let currentIndex = -1; + for (let index = 0; index < (props as any).originData.content.origin.summary.length; index++) { + const item = (props as any).originData.content.origin.summary[index]; + if (item.agent_key === curAgentKey) { + currentIndex++; + if (index === props.summaryIndex) { + break; + } + } + } + + const newSummary = res?.summary?.[currentIndex]; + if (!newSummary) return; + + updateCurrent(newSummary); +}; + +const updateIndexSummary = (summary) => { + updateCurrent(summary?.[props.summaryIndex], true); +}; defineExpose({ drawChart, isMultiCompare, handleMultiCompare, handleData, + updateAll, + + updateIndexSummary, }); </script> <style scoped lang="scss"></style> -- Gitblit v1.9.3