| | |
| | | <!-- 昨日供水管网概况 --> |
| | | <template> |
| | | <div class="w-full"> |
| | | <div class="flex mb-4 flex-wrap" v-if="visibleParams && visibleParams.length > 0"> |
| | | <div class="flex mb-4 flex-wrap"> |
| | | <!-- TimeRange v-model 跟 @change 中的值会不一样,以@change 中为准 --> |
| | | <component |
| | | class="flex-0 m-1" |
| | | v-model="paramsValueList[index].value" |
| | | v-for="(item, index) in visibleParams as any" |
| | | :key="item.id" |
| | | :id="item.id" |
| | | :is="recordSetMapCom[item.type]" |
| | | :data="item" |
| | | :originData="originData" |
| | | @change="(val) => handleQueryChange(val, item)" |
| | | :disabled="chartLoading" |
| | | ></component> |
| | | <template v-if="visibleParams && visibleParams.length > 0"> |
| | | <component |
| | | class="flex-0 m-1" |
| | | v-model="paramsValueList[index].value" |
| | | v-for="(item, index) in visibleParams as any" |
| | | :key="item.id" |
| | | :id="item.id" |
| | | :is="recordSetMapCom[item.type]" |
| | | :data="item" |
| | | :originData="originData" |
| | | @change="(val) => handleQueryChange(val, item)" |
| | | :disabled="chartLoading" |
| | | ></component> |
| | | </template> |
| | | <slot> </slot> |
| | | |
| | | <YRange v-model="yRange" @input="yRangeInput" /> |
| | | <el-checkbox class="m-1" v-model="isMultiCompare" label="多日对比" @change="multiCompareChange"></el-checkbox> |
| | | </div> |
| | | <div class="h-[20rem]" v-resize="chartContainerResize" v-loading="chartLoading"> |
| | | <div :style="{ height: chartHeight }" v-resize="chartContainerResize" v-loading="chartLoading"> |
| | | <div ref="chartRef"></div> |
| | | </div> |
| | | </div> |
| | |
| | | import { filterQuery } from '/@/api/ai/chat'; |
| | | import { deepClone } from '/@/utils/other'; |
| | | import { debounce } from '/@/utils/util'; |
| | | import { ChartTypeEnum } from '../../../types'; |
| | | |
| | | const chartRef = ref<HTMLDivElement>(null); |
| | | const defaultDisplayType = 'line'; |
| | |
| | | }, |
| | | summaryIndex: { |
| | | type: Number, |
| | | }, |
| | | chartHeight: { |
| | | type: String, |
| | | default: '20rem', |
| | | }, |
| | | }) as { |
| | | data: RecordSet; |
| | |
| | | } else { |
| | | newList.push(current); |
| | | } |
| | | }else{ |
| | | } else { |
| | | newList.push(current); |
| | | } |
| | | } |
| | |
| | | let valueCol = null; |
| | | |
| | | let preData = null; |
| | | |
| | | let activeChartType: ChartTypeEnum = ChartTypeEnum.Line; |
| | | |
| | | const getChartTypeSeriesOption = (type: ChartTypeEnum) => { |
| | | let result = {}; |
| | | switch (type) { |
| | | case ChartTypeEnum.Bar: |
| | | result = { |
| | | type: 'bar', |
| | | symbol: 'none', |
| | | }; |
| | | |
| | | break; |
| | | case ChartTypeEnum.Line: |
| | | result = { |
| | | type: 'line', |
| | | symbol: 'none', |
| | | smooth: true, |
| | | }; |
| | | |
| | | break; |
| | | |
| | | case ChartTypeEnum.Scatter: |
| | | result = { |
| | | type: 'scatter', |
| | | symbol: 'circle', |
| | | symbolSize: SCATTER_SYMBOL_SIZE, |
| | | }; |
| | | |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return result; |
| | | }; |
| | | |
| | | const setNewOption = (series?: any[], extraOption: echarts.EChartsOption = {}) => { |
| | | const isEmpty = !series || series.length === 0; |
| | |
| | | feature: { |
| | | myBar: { |
| | | onclick: () => { |
| | | activeChartType = ChartTypeEnum.Bar; |
| | | chartInstance.value.setOption({ |
| | | series: series.map((item) => ({ |
| | | ...item, |
| | | type: 'bar', |
| | | symbol: 'none', |
| | | ...getChartTypeSeriesOption(activeChartType), |
| | | })), |
| | | }); |
| | | }, |
| | |
| | | |
| | | myScatter: { |
| | | onclick: () => { |
| | | activeChartType = ChartTypeEnum.Scatter; |
| | | |
| | | chartInstance.value.setOption({ |
| | | series: series.map((item) => ({ |
| | | ...item, |
| | | type: 'scatter', |
| | | symbol: 'circle', |
| | | symbolSize: SCATTER_SYMBOL_SIZE, |
| | | ...getChartTypeSeriesOption(activeChartType), |
| | | })), |
| | | }); |
| | | }, |
| | | }, |
| | | myLine: { |
| | | onclick: () => { |
| | | activeChartType = ChartTypeEnum.Line; |
| | | chartInstance.value.setOption({ |
| | | series: series.map((item) => ({ |
| | | ...item, |
| | | type: 'line', |
| | | symbol: 'none', |
| | | smooth: true, |
| | | ...getChartTypeSeriesOption(activeChartType), |
| | | })), |
| | | }); |
| | | }, |
| | |
| | | }); |
| | | }; |
| | | |
| | | const drawChart = () => { |
| | | const handleData = () => { |
| | | const data = props.data; |
| | | if (!data || !data.cols || !data.values) { |
| | | return; |
| | | } |
| | | preData = data; |
| | | const xType = 'time'; |
| | | timeIndex = data.cols.findIndex((item) => item.type === 'time'); |
| | |
| | | nameCol = data.cols[nameIndex]; |
| | | groupedValues = _.groupBy(data.values, (item) => item[nameIndex]); |
| | | } |
| | | }; |
| | | |
| | | const drawChart = () => { |
| | | const data = props.data; |
| | | if (!data || !data.cols || !data.values) { |
| | | return; |
| | | } |
| | | handleData(); |
| | | setNewOption(); |
| | | }; |
| | | const { chartContainerResize, chartInstance } = useDrawChatChart({ chartRef, drawChart }); |
| | |
| | | let res = null; |
| | | |
| | | try { |
| | | if(item.type===RecordSetParamsType.TimeRange){ |
| | | changeMap.set(item.range[0].id,val[0]), |
| | | changeMap.set(item.range[1].id,val[1]) |
| | | }else{ |
| | | 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 = {}; |
| | |
| | | } |
| | | }; |
| | | |
| | | const getSingleDayOption = (day=COMMON_DAY) => ({ |
| | | tooltip: { |
| | | show: true, |
| | | trigger: 'axis', |
| | | formatter(params) { |
| | | const itemList = params.map((item, index) => { |
| | | return `<div style="margin: ${index === 0 ? 0 : 10}px 0 0; line-height: 1"> |
| | | <div style="margin: 0px 0 0; line-height: 1"> |
| | | ${item.marker}<span style="font-size: 14px; color: #666; font-weight: 400; margin-left: 2px" |
| | | >${item.seriesName}</span |
| | | ><span style="float: right; margin-left: 20px; font-size: 14px; color: #666; font-weight: 900">${item.data[1]}</span> |
| | | <div style="clear: both"></div> |
| | | </div> |
| | | <div style="clear: both"></div> |
| | | </div>`; |
| | | }); |
| | | |
| | | const result = `<div style="margin: 0px 0 0; line-height: 1"> |
| | | <div style="margin: 0px 0 0; line-height: 1"> |
| | | <div style="font-size: 14px; color: #666; font-weight: 400; line-height: 1">${params?.[0]?.data[0]?.slice(10, 16)}</div> |
| | | <div style="margin: 10px 0 0; line-height: 1"> |
| | | ${itemList.join('')} |
| | | <div style="clear: both"></div> |
| | | </div> |
| | | <div style="clear: both"></div> |
| | | </div> |
| | | <div style="clear: both"></div> |
| | | </div>`; |
| | | return result; |
| | | }, |
| | | }, |
| | | xAxis: { |
| | | min: day + ' 00:00:00', |
| | | max: day + ' 23:59:59', |
| | | splitNumber: 10, |
| | | axisLabel: { |
| | | formatter: (val) => { |
| | | const newVal = moment(val).format('HH:mm'); |
| | | return newVal; |
| | | }, |
| | | showMaxLabel: true, |
| | | }, |
| | | }, |
| | | } as echarts.EChartsOption); |
| | | //#region ====================== 设置Y范围 ====================== |
| | | const debounceSetYRange = debounce((val) => { |
| | | chartInstance.value.setOption({ |
| | |
| | | const series = seriesData.map<echarts.SeriesOption>((item) => ({ |
| | | name: item[0]?.[nameIndex], |
| | | data: item.map((item) => [item[timeIndex], item[valueIndex]]), |
| | | type: defaultDisplayType, |
| | | symbol: 'none', |
| | | smooth: true, |
| | | ...getChartTypeSeriesOption(activeChartType), |
| | | })); |
| | | setNewOption(series, { |
| | | tooltip: { |
| | | show: true, |
| | | trigger: 'axis', |
| | | formatter(params) { |
| | | const itemList = params.map((item, index) => { |
| | | return `<div style="margin: ${index === 0 ? 0 : 10}px 0 0; line-height: 1"> |
| | | <div style="margin: 0px 0 0; line-height: 1"> |
| | | ${item.marker}<span style="font-size: 14px; color: #666; font-weight: 400; margin-left: 2px" |
| | | >${item.seriesName}</span |
| | | ><span style="float: right; margin-left: 20px; font-size: 14px; color: #666; font-weight: 900">${item.data[1]}</span> |
| | | <div style="clear: both"></div> |
| | | </div> |
| | | <div style="clear: both"></div> |
| | | </div>`; |
| | | }); |
| | | |
| | | const result = `<div style="margin: 0px 0 0; line-height: 1"> |
| | | <div style="margin: 0px 0 0; line-height: 1"> |
| | | <div style="font-size: 14px; color: #666; font-weight: 400; line-height: 1">${params?.[0]?.data[0]?.slice(10, 16)}</div> |
| | | <div style="margin: 10px 0 0; line-height: 1"> |
| | | ${itemList.join('')} |
| | | <div style="clear: both"></div> |
| | | </div> |
| | | <div style="clear: both"></div> |
| | | </div> |
| | | <div style="clear: both"></div> |
| | | </div>`; |
| | | return result; |
| | | }, |
| | | }, |
| | | xAxis: { |
| | | min: COMMON_DAY + ' 00:00:00', |
| | | max: COMMON_DAY + ' 23:59:59', |
| | | splitNumber: 10, |
| | | axisLabel: { |
| | | formatter: (val) => { |
| | | const newVal = moment(val).format('HH:mm'); |
| | | return newVal; |
| | | }, |
| | | showMaxLabel: true, |
| | | }, |
| | | }, |
| | | }); |
| | | setNewOption(series, getSingleDayOption()); |
| | | }; |
| | | const multiCompareChange = (val) => { |
| | | if (!groupedValues) return; |
| | |
| | | } |
| | | }; |
| | | //#endregion |
| | | |
| | | defineExpose({ |
| | | drawChart, |
| | | isMultiCompare, |
| | | handleMultiCompare, |
| | | handleData, |
| | | }); |
| | | </script> |
| | | <style scoped lang="scss"></style> |