效果圖:
<script setup lang="ts"> import * as echarts from 'echarts'; import { ref, watch, nextTick, computed } from 'vue'; import { useRouteParams } from '@/hooks/useRouteParams'; import { queryIncreaseTrend } from '@/api/warning'; import { formatPercent } from '@/utils/util'; import dayjs from 'dayjs'; import moment from 'moment'; const props = defineProps({ originData: { type: Array, default: () => { return []; } }, params: { type: Object, default: () => {} } }); // @ts-ignore let myChart: any = null; const dailyChartRef = ref(); // @ts-ignore const data1 = ref<any>([]); // @ts-ignore const data2 = ref<any>([]); const dataNames = ref<any>([]); const statDate = ref<any>([]); const dateType = ref(props.params.period); const statDateBegin = ref(props.params.statDateBeginStr); const statDateEnd = ref(props.params.statDateEndStr); const curId = ref(props.params.curId); const DTD = ref(props.params.DTD); const colors = ['#03B7D9', '#B2B6C5']; const chartConfig = computed(() => { let data11 = []; let data12 = []; let data21 = []; let data22 = []; let dateIndex = statDate.value.indexOf(moment(statDateBegin.value).format('YYYYMMDD')); data11 = data1.value.map((v, i) => { if (i < dateIndex) { return undefined; } else { return v; } }); data12 = data1.value.map((v, i) => { if (i <= dateIndex) { return v; } else { return undefined; } }); data21 = data2.value.map((v, i) => { if (i < dateIndex) { return undefined; } else { return v; } }); data22 = data2.value.map((v, i) => { if (i <= dateIndex) { return v; } else { return undefined; } }); return { color: colors, title: { show: false, text: '近4周業務增速', left: 10, textStyle: { color: '#303133', fontWeight: 500 }, padding: [5, 10, 40, 0] }, grid: { left: '14%', top: '14%', right: '10%' }, legend: { data: ['增速1', '行業增速'], selected: { 增速1: true, 行業增速: true }, bottom: 10, icon: 'rect', itemWidth: 10, itemHeight: 2 }, tooltip: { show: true, trigger: 'axis', // formatter: `{b0}<br/>{a0}: {c0}%<br />{a1}: {c1}%`, backgroundColor: 'rgba(50,50,50,0.8)', borderColor: 'rgba(57, 56, 56, 0.8)', textStyle: { color: 'rgba(255, 255, 255, 1)' }, formatter: function (params, ticket, callback) { var htmlStr = ''; var valMap = {}; for (var i = 0; i < params.length; i++) { var param = params[i]; var xName = param.name; //x軸的名稱 var seriesName = param.seriesName; //圖例名稱 var value = param.value; //y軸值 var color = param.color; //圖例顏色 //過濾無效值 if (value == undefined) { continue; } //過濾重疊值 if (valMap[seriesName] == value) { continue; } if (i === 0) { htmlStr += xName + '<br/>'; //x軸的名稱 } htmlStr += '<div>'; //為了保證和原來的效果一樣,這裡自己實現了一個點的效果 htmlStr += '<span style="margin-right:5px;display:inline-block;width:10px;height:10px;border-radius:5px;background-color:' + color + ';"></span>'; //圓點後面顯示的文字 htmlStr += seriesName + ':' + value; htmlStr += '</div>'; valMap[seriesName] = value; } return htmlStr; } }, xAxis: [ { type: 'category', axisTick: { alignWithLabel: true }, data: [], axisLabel: { // rotate: 0, // 旋轉標籤,根據實際情況調整角度 // margin: 20, // 標籤與軸線之間的距離 interval: 0 // 強制顯示所有標籤 }, boundaryGap: false } ], yAxis: [ { type: 'value', name: '率值', position: 'left', // min: 0, // axisLine: { // show: false // }, axisLabel: { formatter: '{value}%' } } ], series: [ { name: '增速1', type: 'line', data: data11, symbolSize: 0, smooth: true, color: '#03B7D9' }, { name: '增速1', type: 'line', data: data12, symbolSize: 0, smooth: true, color: '#B2B6C5' }, { name: '行業增速', type: 'line', data: data21, symbolSize: 0, smooth: true, color: 'rgba(63, 103, 229, 1)' }, { name: '行業增速', type: 'line', data: data22, symbolSize: 0, smooth: true, color: '#B2B6C5' } ] }; }); const initChart = () => { if (dailyChartRef.value) { // @ts-ignore if (!myChart) { myChart = echarts.init(dailyChartRef.value); } else { // @ts-ignore myChart.clear(); } chartConfig.value.xAxis[0].data = dataNames.value; myChart && myChart.setOption(chartConfig.value); setTimeout(() => { myChart && myChart.resize(); }, 1000); myChart.on('legendselectchanged', function (params: any) { let option = chartConfig.value; let selected_value = Object.values(params.selected); if (selected_value.every((val) => !val)) { option.legend[0].selected[params.name] = true; } myChart.setOption(option); }); } }; const init = async () => { const commonParams = { manageAreaId: curId.value, queryType: dateType.value, startTimeStr: dayjs(statDateBegin.value).format('YYYY/MM/DD'), endTimeStr: dayjs(statDateEnd.value).format('YYYY/MM/DD') }; console.log(commonParams); let res: any = await queryIncreaseTrend(commonParams); dataNames.value = []; statDate.value = []; data1.value = []; data2.value = []; if (res) { res.forEach((item: any, index: number) => { statDate.value[index] = item.statDate; dataNames.value[index] = item.timeSection; data1.value[index] = formatPercent(item.ztoIncreaseRate, 2, false); data2.value[index] = formatPercent(item.industryIncreaseRate, 2, false); }); } nextTick(() => { initChart(); }); }; watch( () => props.params, (val, oldVal) => { if (val) { // if (val.statDateBeginStr == val.statDateEndStr) return console.log(val); dateType.value = val.period; statDateBegin.value = val.statDateBeginStr; statDateEnd.value = val.statDateEndStr; DTD.value = val.DTD; if (val.curId) { curId.value = Number(val.curId); } init(); } }, { // immediate: true, deep: true } ); </script> <template> <div class="line-box"> <div class="title">業務增速近7天趨勢</div> <div ref="dailyChartRef" class="line-echarts"></div> </div> </template> <style scoped lang="scss"> .line-box { background: #fff; border-radius: 8px; color: #303133; padding-top: 16px; //padding: 16px; .title { font-size: 17px; font-weight: bold; padding-left: 16px; .text { font-size: 13px; } } .line-echarts { width: 100%; height: 220px; } } </style>