| | |
| | | :data="item" |
| | | :originData="originData" |
| | | @change="(val) => handleQueryChange(val, item)" |
| | | :disabled="chartLoading ||disabled" |
| | | :disabled="chartLoading || disabled" |
| | | ></component> |
| | | </template> |
| | | <slot> </slot> |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import type * as echarts from 'echarts'; |
| | | import _ from 'lodash'; |
| | | import moment from 'moment'; |
| | | import type { PropType } from 'vue'; |
| | | import { computed, ref, shallowRef, watch } from 'vue'; |
| | |
| | | import RecordSetTable from '../recordSetTable/RecordSetTable.vue'; |
| | | import DisplayMode from './components/DisplayMode.vue'; |
| | | import YRange from './components/YRange.vue'; |
| | | import { IS_DAY_LIST } from './components/constants'; |
| | | import { DisplayModeType } from './components/types'; |
| | | import type { RecordSetParamsItem } from './types'; |
| | | import { RecordSetParamsType, recordSetMapCom, scoreMap } from './types'; |
| | |
| | | import { axisLabelFormatter } from '/@/utils/chart'; |
| | | import { deepClone } from '/@/utils/other'; |
| | | import { debounce } from '/@/utils/util'; |
| | | import { IS_DAY_LIST } from './components/constants'; |
| | | import { defaultsDeep, groupBy, random } from 'lodash-es'; |
| | | const chartRef = ref<HTMLDivElement>(null); |
| | | |
| | | const showMode = ref(DisplayModeType.Chart); |
| | |
| | | type: String, |
| | | required: false, |
| | | }, |
| | | tableHeight: { |
| | | type: Number, |
| | | default: document.body.clientHeight * 0.7, |
| | | }, |
| | | showFilter: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | disabled:{ |
| | | type:Boolean, |
| | | default:false, |
| | | } |
| | | }) as { |
| | | data: any; |
| | | summaryIndex: number; |
| | | showFilter: Boolean; |
| | | }; |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | reportIndex: { |
| | | type: Number, |
| | | default: 0, |
| | | }, |
| | | historyId: { |
| | | type: String, |
| | | }, |
| | | }); |
| | | |
| | | const tableLimitHeight = props.chartHeight == undefined ? undefined : document.body.clientHeight * 0.7; |
| | | const tableLimitHeight = props.chartHeight == undefined ? undefined : props.tableHeight; |
| | | |
| | | const chartLoading = ref(false); |
| | | |
| | |
| | | const getVisibleParams = (data) => { |
| | | // const visibleList = props.data?.params?.filter((item) => !item?.hide) ?? []; |
| | | // index 作为 id |
| | | const dataFilter = data?.filter ?? []; |
| | | const visibleList = (data?.filter ?? []).map((item, index) => { |
| | | // 不修改原始地址 |
| | | item.id = index + ''; |
| | |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const visibleParams = ref(getVisibleParams(props.data)); |
| | | |
| | | const checkIsDayTime = () => { |
| | |
| | | const values = groupedValues[item]; |
| | | return { |
| | | name: item === 'default' ? '' : item, |
| | | data: values.map((item) => [item[timeIndex], item[valueIndex]]), |
| | | data: values |
| | | .map((item) => [item[timeIndex], item[valueIndex]]) |
| | | .toSorted((b, a) => { |
| | | return b[timeIndex].localeCompare(a[timeIndex]); |
| | | }), |
| | | ...getChartTypeSeriesOption(activeChartType), |
| | | }; |
| | | }); |
| | |
| | | } |
| | | : axisLabelFormatter; |
| | | |
| | | const tooltipValueFormatter = |
| | | originChartType === ChartTypeEnum.Score |
| | | ? (value) => { |
| | | return scoreMap[value]; |
| | | } |
| | | : undefined; |
| | | const tooltipValueFormatter = (value) => { |
| | | const realValue = originChartType === ChartTypeEnum.Score ? scoreMap[value] : value; |
| | | return realValue + (props.data.unit ? ` ${props.data.unit}` : ''); |
| | | }; |
| | | |
| | | const scoreYAxisOption: echarts.YAXisComponentOption = { |
| | | min: 0, |
| | |
| | | formatter: yAxisFormatter, |
| | | }, |
| | | }; |
| | | const combineOption = _.defaultsDeep( |
| | | const combineOption = defaultsDeep( |
| | | { |
| | | grid: { |
| | | bottom: 20, |
| | |
| | | name: timeCol?.title, |
| | | }, |
| | | yAxis: { |
| | | name: valueCol?.title, |
| | | name: props.data.unit ? `${props.data.unit}` : valueCol?.title, |
| | | |
| | | /** @description 不强制保留 */ |
| | | scale: true, |
| | | ...(originChartType === ChartTypeEnum.Score ? scoreYAxisOption : {}), |
| | |
| | | nameIndex = 1; |
| | | } |
| | | nameCol = data.cols[nameIndex]; |
| | | groupedValues = _.groupBy(data.values, (item) => item[nameIndex]); |
| | | groupedValues = groupBy(data.values, (item) => item[nameIndex]); |
| | | } else if (data.chart === 'single_line') { |
| | | groupedValues = { |
| | | default: data.values, |
| | |
| | | nameIndex = 1; |
| | | } |
| | | nameCol = data.cols[nameIndex]; |
| | | groupedValues = _.groupBy(data.values, (item) => item[nameIndex]); |
| | | groupedValues = groupBy(data.values, (item) => item[nameIndex]); |
| | | } |
| | | }; |
| | | |
| | |
| | | if (!data || !data.cols || !data.values) { |
| | | return; |
| | | } |
| | | |
| | | handleData(); |
| | | setNewOption(); |
| | | }; |
| | |
| | | // 只更新 value,不直接覆盖,防止丢失响应性 |
| | | // updateVisibleParams(res); |
| | | //#endregion |
| | | groupedValues = _.groupBy(values, (item) => item[nameIndex]); |
| | | groupedValues = groupBy(values, (item) => item[nameIndex]); |
| | | if (isMultiCompare.value) { |
| | | handleMultiCompare(); |
| | | } else { |
| | |
| | | const values = groupedValues[item]; |
| | | return { |
| | | name: item === 'default' ? '' : item, |
| | | data: values.map((item) => [item[timeIndex], item[valueIndex]]), |
| | | data: values |
| | | .map((item) => [item[timeIndex], item[valueIndex]]) |
| | | .toSorted((b, a) => { |
| | | return b[timeIndex].localeCompare(a[timeIndex]); |
| | | }), |
| | | }; |
| | | })), |
| | | chartInstance.value?.setOption({ |
| | |
| | | } |
| | | }; |
| | | |
| | | const getFilterList = () => { |
| | | const curAgentKey = props.data.agent_key; |
| | | |
| | | // 相同 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; |
| | | }, []); |
| | | return filterList; |
| | | }; |
| | | const handleQueryChange = async (val: any, item: RecordSetParamsItem) => { |
| | | if (!val) return; |
| | | const historyId = (props as any).originData.historyId; |
| | | const curAgentKey = props.data.agent_key; |
| | | const historyId = props.historyId; |
| | | let res = null; |
| | | |
| | | // 改变原始值 |
| | |
| | | } else { |
| | | item.origin.step_value = val; |
| | | } |
| | | |
| | | const filterList = getFilterList(); |
| | | try { |
| | | // 相同 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, |
| | | // 查询前后 agent_key 不会变 |
| | | agent_key: props.data.agent_key, |
| | | filter_json: JSON.stringify(filterList), |
| | | result_group_index: props.reportIndex, |
| | | }; |
| | | res = await curveQuery(params); |
| | | chartLoading.value = true; |
| | |
| | | const seriesData = Object.keys(cloneData).reduce((preVal, curVal, curIndex, arr) => { |
| | | const values = cloneData[curVal]; |
| | | const isMulti = arr.length > 1; |
| | | const groupByDateValues = _.groupBy(values, (item) => moment(item[timeIndex]).format('YYYY-MM-DD')); |
| | | const groupByDateValues = groupBy(values, (item) => moment(item[timeIndex]).format('YYYY-MM-DD')); |
| | | for (const key in groupByDateValues) { |
| | | if (Object.prototype.hasOwnProperty.call(groupByDateValues, key)) { |
| | | const val = groupByDateValues[key]; |
| | |
| | | }, []); |
| | | const series = seriesData.map<echarts.SeriesOption>((item) => ({ |
| | | name: item[0]?.[nameIndex], |
| | | data: item.map((item) => [item[timeIndex], item[valueIndex]]), |
| | | data: item |
| | | .map((item) => [item[timeIndex], item[valueIndex]]) |
| | | .toSorted((b, a) => { |
| | | return b[timeIndex].localeCompare(a[timeIndex]); |
| | | }), |
| | | ...getChartTypeSeriesOption(activeChartType), |
| | | })); |
| | | setNewOption(series, getSingleDayOption()); |
| | |
| | | return preVal; |
| | | }, {}); |
| | | |
| | | const data = Object.keys(timeDataMap).map((item) => [item, ...timeDataMap[item]]); |
| | | // 时间最早到最晚排序 |
| | | const data = Object.keys(timeDataMap) |
| | | .map((item) => [item, ...timeDataMap[item]]) |
| | | .toSorted((b, a) => { |
| | | return b[0].localeCompare(a[0]); |
| | | }); |
| | | const getColName = (name) => { |
| | | if (props.data.unit) { |
| | | return `${name}(${props.data.unit})`; |
| | | } |
| | | return name; |
| | | }; |
| | | const cols = currentSeries.value.map((item, index) => ({ |
| | | title: item.name ?? `值${index + 1}`, |
| | | title: getColName(item.name ?? `值${index + 1}`), |
| | | type: 'text', |
| | | })); |
| | | |
| | | cols.unshift({ |
| | | title: '时间', |
| | | type: 'time', |
| | |
| | | cols: cols, |
| | | values: data, |
| | | }; |
| | | |
| | | return result; |
| | | }); |
| | | //#endregion |
| | |
| | | watch( |
| | | () => currentSeries.value, |
| | | (val) => { |
| | | tableKey.value = _.random(0, 100000) + ''; |
| | | tableKey.value = random(0, 100000) + ''; |
| | | } |
| | | ); |
| | | |
| | |
| | | updateCurrent(summary?.[props.summaryIndex], true); |
| | | }; |
| | | |
| | | const clearChart = () => { |
| | | chartInstance.value.setOption( |
| | | { |
| | | title: { |
| | | text: '', |
| | | }, |
| | | series: [], |
| | | }, |
| | | true |
| | | ); |
| | | }; |
| | | |
| | | defineExpose({ |
| | | drawChart, |
| | | isMultiCompare, |
| | | handleMultiCompare, |
| | | handleData, |
| | | updateAll, |
| | | |
| | | clearChart, |
| | | updateIndexSummary, |
| | | }); |
| | | </script> |