HeatMap.nvue 4.81 KB
<template>
	<view style="margin-bottom: 20rpx;">
		<CardNvue :title="t('PreMallChart.mall_period_passenger_flow_heat.table')">
			<template #filter>
				<view class="filter filter-border transparent-bg" @tap="handleTapToChoose">
					<text class="filter_text">{{ selectText || t('maintenance.common.select') }}</text>
          <uv-icon name="arrow-right" color="#90949D" size="24rpx" />
				</view>
			</template>
			<template #content>
				<ChartsNvue ref="chartsRef" />
			</template>
		</CardNvue>
		<uv-popup ref="typePopRef">
			<view class="pop_header">
				<view style="width: 22px;"></view>
				<text class="pop_header_text">{{ t('app.title.kpiSelect') }}</text>
				<uv-icon name="close" size="22" class="pop_header_icon" @tap="handleCloseTypeSelect"></uv-icon>
			</view>
			<view class="l_type">
				<view class="l_type_item" v-for="(item,index) in getIndicator" :key="item.indexKey"
					:class="{'l_type_item_active':index === checkIndex}" @tap="handleChangeCheckType(index)">
					<text class="l_type_item_text"
						:class="{'l_type_item_active_text':index === checkIndex}">{{ item.indexName }}</text>
				</view>
			</view>
		</uv-popup>
	</view>
</template>

<script setup>
	import {
		getThermodynamicMallApi
	} from '@/api'
	import CardNvue from './Card.nvue'
	import ChartsNvue from '@/components/Charts.nvue'
	import {
		computed,
		onMounted,
		ref
	} from 'vue'
  import {
    t
  } from '@/plugins/index.js'

	/**************************** pop选择相关 *********************************/
	const typePopRef = ref(null)
	const checkIndex = ref('')
	const selectIndex = ref(0)
	const selectText = computed(() => {
		return getIndicator.value?.[selectIndex.value]?.indexName
	})
	const handleTapToChoose = () => {
		checkIndex.value = selectIndex.value || 0
		typePopRef.value?.open('bottom')
	}
	const handleCloseTypeSelect = () => {
		typePopRef.value?.close()
	}
	const handleChangeCheckType = (index) => {
		checkIndex.value = index
		handleConfirmSelectType()
	}
	const handleConfirmSelectType = () => {
		selectIndex.value = checkIndex.value
		typePopRef.value?.close()
		getTrendChartData()
	}


	const selfIndicators = ['PassByCount', 'EnterCount', 'CustomerMantime', 'CustomerNum']


	const getIndicator = computed(() => {
		return props.indicators.filter(item => selfIndicators.includes(item.indexKey))
	})

	const props = defineProps({
		indicators: {
			type: Array,
			default: () => []
		}
	})

	const chartsRef = ref(null)


	const options = ref({})
	const initData = (params) => {
		options.value = params
		getTrendChartData()
	}
	defineExpose({
		initData
	})

	const getTrendChartData = async () => {
		try {
			// 参数设置位置:
			const params = {
				startDate: options.value.startDate,
				endDate: options.value.endDate,
				chartIds: 267,
				orgIds: options.value.storeId,
				index: getIndicator.value?.[selectIndex.value]?.indexKey || '',
			}
			const {
				data
			} = await getThermodynamicMallApi(params)
			const {
				TimeThermodynamic
			} = data.body

			renderCharts(TimeThermodynamic)
		} catch (e) {
			console.log(e);
		}
	}

	const renderCharts = (val = {
		series: [],
		title: '',
		xaxis: {
			data: []
		}
	}) => {

		// prettier-ignore
		const days = val.series.map(el=> el.name) || [];
		const daysDataMap = {}
		const dataLength = val.xaxis.data.length

		for (let item of val.series) {
			daysDataMap[item.name] = item.data
		}
		const dataListByDays = days.map(day => {
			return daysDataMap[day] || Array(dataLength).fill(0)
		}) || []
    
		const seriesVal = []

		dataListByDays.map((_, yIndex) => {
			_?.map((item, dataIndex) => {
				seriesVal.push([parseInt(yIndex), dataIndex, item || "-"])
			})
		})
		let max = 0
		const data = seriesVal.map(function(item) {
			max = Math.max(item[2] === '-' ? 0 : item[2], max)
			return [item[1], item[0], item[2] || '-'];
		});
		const option = {
			tooltip: {
				position: 'top',
        confine:true,
        triggerOn:'click'
			},
			grid: {
				top: 10,
				bottom: 20,
				right: 0,
				left: 34,
			},
			xAxis: {
				type: 'category',
				data: val.xaxis.data,
				splitArea: {
					show: true
				},
				axisTick: {
					show: false
				}
			},
			yAxis: {
				type: 'category',
				data: days,
				splitArea: {
					show: true,
				},
				axisTick: {
					show: false
				}
			},
			visualMap: {
				min: 0,
				max: max || 1,
        show:false,
				calculable: true,
				type: 'continuous',
				orient: 'horizontal',
				right: 0,
				top: '0',
				inRange: {
					color: ["#99ddff", "#0022FF"]
				}
			},
			series: [{
				name: t('echarts.averageThermal'),
				type: 'heatmap',
				data: data,
				label: {
					show: false
				},
				// emphasis: {
				// 	itemStyle: {
				// 		shadowBlur: 10,
				// 		shadowColor: 'rgba(0, 0, 0, 0.5)'
				// 	}
				// }
			}]
		};
		chartsRef.value?.initCharts(option)
	}
</script>

<style lang="scss">
	@import '@/styles/normal.scss'
</style>