根据按钮和日期范围选择器的日期范围来控制图表X轴的显示(日期格式化)
需求:
上方的按钮和时间选择器控制下方柱状图的X轴(时间范围);本周:包括今天在内的过去7天,本月:这一个月的所有天,全年:本年的所有月;日期范围框的时间在表格中显示为 日
html:
<el-card style="margin-top: 20px;"> <div class="button-container"> <el-button type="text" @click="setTimeRange('week')">本周</el-button> <el-button type="text" @click="setTimeRange('month')">本月</el-button> <el-button type="text" @click="setTimeRange('year')">全年</el-button> <el-date-picker v-model="timeRange" type="daterange" format="yyyy-MM-dd" placeholder="选择日期范围" @change="handleDateChange" style="margin-left: 10px;" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" /> </div> <div style="display:flex"> <div style="width: 65%;"> <div class="title"> <div></div> <p>全院考核活动扣分趋势</p> </div> <div id="barChart" style="height: 300px;"></div> </div> <div style="width: 35%;"> <div class="title"> <div></div> <p>全院考核活动扣分趋势</p> </div> <el-table :data="tableData" style="width: 100%"> <el-table-column label="排名" prop="rank"> <template #default="scope"> <span :style="getRankStyle(scope.row.rank)">{{ scope.row.rank }}</span> </template> </el-table-column> <el-table-column label="科室" prop="department"></el-table-column> <el-table-column label="扣分次数" prop="scoreCount"></el-table-column> </el-table> </div> </div> </el-card>
js:
1 <script> 2 import * as echarts from "echarts"; 3 4 export default { 5 data() { 6 return { 7 timeRange: [], // 保存选择的日期范围 8 barChart: null, // ECharts 实例 9 tableData: [ 10 { rank: 1, department: '心内科', scoreCount: 10 }, 11 { rank: 2, department: '神经内科', scoreCount: 9 }, 12 { rank: 3, department: '麻醉科', scoreCount: 8 }, 13 { rank: 4, department: '重症科', scoreCount: 7 }, 14 { rank: 5, department: '呼吸内科', scoreCount: 6 }, 15 { rank: 6, department: '肾内科', scoreCount: 5 }, 16 ], 17 }; 18 }, 19 mounted() { 20 this.barChart = echarts.init(document.getElementById('barChart')); // 通过 id 初始化 ECharts 实例 21 this.updateBarChart('month'); // 默认显示本月数据 22 }, 23 methods: { 24 25 setTimeRange(period) { 26 const now = new Date(); 27 if (period === 'week') { 28 const startOfWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay() + 1); // 从周一开始 29 const endOfWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay() + 7); // 到下周日 30 this.timeRange = [startOfWeek.toISOString().split('T')[0], endOfWeek.toISOString().split('T')[0]]; 31 console.log('this.timeRange :', this.timeRange); 32 } else if (period === 'month') { 33 const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); 34 const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0); 35 this.timeRange = [startOfMonth.toISOString().split('T')[0], endOfMonth.toISOString().split('T')[0]]; 36 } else if (period === 'year') { 37 const startOfYear = new Date(now.getFullYear(), 0, 1); 38 const endOfYear = new Date(now.getFullYear(), 11, 31); 39 this.timeRange = [startOfYear.toISOString().split('T')[0], endOfYear.toISOString().split('T')[0]]; 40 } 41 this.updateBarChart(period); 42 }, 43 handleDateChange(dates) { 44 if (dates && dates.length === 2) { 45 this.timeRange = dates; 46 this.updateBarChart('custom'); 47 } 48 }, 49 updateBarChart(period) { 50 let xAxisData = []; 51 let seriesData = []; 52 const today = new Date(); // 先保存今天的日期 53 if (period === 'custom') { // 自定义日期范围 54 const startDate = new Date(this.timeRange[0]); 55 const endDate = new Date(this.timeRange[1]); 56 57 // 生成日期范围内的日期数据 58 let currentDate = startDate; 59 while (currentDate <= endDate) { 60 xAxisData.push(`${currentDate.getMonth() + 1}月${currentDate.getDate()}日`); 61 seriesData.push(Math.floor(Math.random() * 101)); // 随机生成0-100之间的数 62 currentDate.setDate(currentDate.getDate() + 1); // 增加一天 63 } 64 } else { 65 if (period === 'week') { 66 for (let i = 6; i >= 0; i--) { 67 const date = new Date(today); // 每次循环创建一个新的日期对象 68 date.setDate(today.getDate() - i); // 设置日期为今天减去 i 天 69 xAxisData.push(`${date.getMonth() + 1}月${date.getDate()}日`); 70 seriesData.push(Math.floor(Math.random() * 101)); // 随机生成0-100之间的数 71 } 72 } else if (period === 'month') { 73 const daysInMonth = new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0).getDate(); 74 for (let i = 1; i <= daysInMonth; i++) { 75 xAxisData.push(`${i}日`); 76 seriesData.push(Math.floor(Math.random() * 101)); // 随机生成0-100之间的数 77 } 78 } else if (period === 'year') { 79 for (let i = 1; i <= 12; i++) { 80 xAxisData.push(`${i}月`); 81 seriesData.push(Math.floor(Math.random() * 101)); // 随机生成0-100之间的数 82 } 83 } 84 } 85 86 const option = { 87 tooltip: { 88 trigger: 'axis', 89 }, 90 xAxis: { 91 type: 'category', 92 data: xAxisData, 93 // axisLine: { show: false }, // 隐藏X轴坐标轴线条 94 splitLine: { show: false }, // 隐藏X轴分割线 95 }, 96 yAxis: { 97 type: 'value', 98 min: 0, 99 max: 100, 100 axisLine: { show: false }, // 隐藏Y轴坐标轴线条 101 splitLine: { 102 show: true, 103 lineStyle: { 104 type: 'dashed', 105 color: '#e8e8e8', 106 }, 107 }, 108 }, 109 series: [ 110 { 111 name: '扣分次数', 112 type: 'bar', 113 data: seriesData, 114 itemStyle: { 115 color: '#3ba1ff', 116 }, 117 }, 118 ], 119 }; 120 121 this.barChart.setOption(option); 122 }, 123 getRankStyle(rank) { 124 switch (rank) { 125 case 1: 126 return { color: 'red' }; 127 case 2: 128 return { color: 'orange' }; 129 case 3: 130 return { color: 'yellow' }; 131 default: 132 return {}; 133 } 134 }, 135 } 136 } 137 </script>
css:
<style lang="scss" scoped> .title { font-weight: 600; font-size: 18px; color: #333333; line-height: 25px; text-align: left; font-style: normal; display: flex; margin: 0px; } .title>div { width: 5px; height: 18px; background-color: #1384ff; border-radius: 2px; margin-top: 14px; margin-right: 10px; } .title>p { display: block; line-height: 12px; } .charts-container { display: flex; justify-content: space-between; } .chart { width: 30%; height: 200px; } .button-container { display: flex; align-items: center; margin: 16px 0; justify-content: flex-end; /* 确保按钮和选择器靠右 */ /* 设置按钮和选择器的上下边距 */ } </style>
格式化
当月日期格式化为2024-10-25
else if (period === 'month') { const now = new Date(); const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); // 当前月份的1号 const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0); // 当前月份最后一天 // 使用 toLocaleDateString 进行格式化 const options = { year: 'numeric', month: '2-digit', day: '2-digit' }; this.timeRange = [ startOfMonth.toLocaleDateString('en-CA', options), // YYYY-MM-DD 格式 endOfMonth.toLocaleDateString('en-CA', options) ]; this.dateType = '2'; console.log('222timeRange :', this.timeRange); }
日期范围选择器格式化
handleDateChange(dates) { if (dates && dates.length === 2 && dates.every(date => date instanceof Date)) { // 定义一个函数来格式化日期 const formatDate = (date) => { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始计数,所以需要加1 const day = String(date.getDate()).padStart(2, '0'); // 日期需要补零 return `${year}-${month}-${day}`; }; // 对每个日期进行格式化 const formattedDates = dates.map(formatDate); // 更新时间范围 this.timeRange = formattedDates; console.log('this.timeRange :', this.timeRange); } },
完整的(包括当天在内的过去7天,本月1号到月底,本年1月1日到12月31日)
// 日期切换 setTimeRange(period) { const now = new Date(); if (period === 'week') { const startOfWeek = new Date(now); startOfWeek.setDate(now.getDate() - 6); // 设置为过去6天 const endOfWeek = now; this.timeRange = [ startOfWeek.toISOString().split('T')[0], endOfWeek.toISOString().split('T')[0] ]; console.log('111timeRange :', this.timeRange); this.dateType = '2'; } else if (period === 'month') { const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); // 当月的1号 const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0); // 当月最后一天 // 使用 toLocaleDateString 进行格式化 const options = { year: 'numeric', month: '2-digit', day: '2-digit' }; this.timeRange = [ startOfMonth.toLocaleDateString('en-CA', options), // YYYY-MM-DD 格式 endOfMonth.toLocaleDateString('en-CA', options) ]; this.dateType = '2'; console.log('222timeRange :', this.timeRange); } else if (period === 'year') { const startOfYear = new Date(now.getFullYear(), 0, 1); // 当年的1月1日 const endOfYear = new Date(now.getFullYear(), 11, 31); // 当年最后一天 const options = { year: 'numeric', month: '2-digit', day: '2-digit' }; this.timeRange = [ startOfYear.toLocaleDateString('en-CA', options), endOfYear.toLocaleDateString('en-CA', options) ]; console.log('333timeRange :', this.timeRange); this.dateType = '1'; } this.updateBarChart(period); this.getData(); },
页面初始化时默认显示当月,可以这样写:
export default { data() { const now = new Date(); const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); // 当月的1号 const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0); // 当月最后一天 // 使用 toLocaleDateString 进行格式化 const options = { year: 'numeric', month: '2-digit', day: '2-digit' }; return { timeRange: [ startOfMonth.toLocaleDateString('en-CA', options), // YYYY-MM-DD 格式 endOfMonth.toLocaleDateString('en-CA', options) ], } }
对完接口:
// 日期切换 setTimeRange(period) { const now = new Date(); if (period === 'week') { const startOfWeek = new Date(now); startOfWeek.setDate(now.getDate() - 6); // 设置为过去6天 const endOfWeek = now; this.timeRange = [ startOfWeek.toISOString().split('T')[0], endOfWeek.toISOString().split('T')[0] ]; this.dateType = '2'; } else if (period === 'month') { const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); // 当月的1号 const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0); // 当月最后一天 // 使用 toLocaleDateString 进行格式化 const options = { year: 'numeric', month: '2-digit', day: '2-digit' }; this.timeRange = [ startOfMonth.toLocaleDateString('en-CA', options), // YYYY-MM-DD 格式 endOfMonth.toLocaleDateString('en-CA', options) ]; this.dateType = '2'; } else if (period === 'year') { const startOfYear = new Date(now.getFullYear(), 0, 1); // 当年的1月1日 const endOfYear = new Date(now.getFullYear(), 11, 31); // 当年最后一天 const options = { year: 'numeric', month: '2-digit', day: '2-digit' }; this.timeRange = [ startOfYear.toLocaleDateString('en-CA', options), endOfYear.toLocaleDateString('en-CA', options) ]; this.dateType = '1'; } this.getbarChart(period); }, getbarChart(period) { this.loading = true; getAnalyse({ startTime: this.timeRange[0], endTime: this.timeRange[1], type: this.dateType, }).then((response) => { // 全院考核活动扣分趋势 this.updateBarChart(period, response.data.assessmentActivityScoreTrend); // 科室考核活动扣分排名 this.tableData = response.data.assessmentActivityScoreTrendByDept; this.loading = false; }); }, handleDateChange(dates) { if (dates && dates.length === 2 && dates.every(date => date instanceof Date)) { // 定义一个函数来格式化日期 const formatDate = (date) => { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始计数,所以需要加1 const day = String(date.getDate()).padStart(2, '0'); // 日期需要补零 return `${year}-${month}-${day}`; }; // 对每个日期进行格式化 const formattedDates = dates.map(formatDate); // 更新时间范围 this.timeRange = formattedDates; this.getbarChart('custom'); } }, updateBarChart(period, data) { const myChart = echarts.init(document.getElementById('barChart')); let xAxisData = []; let seriesData = []; if (period === 'custom' && data) { // 处理后端返回的数据 data.forEach(item => { const year = item.startDate.split('-')[0]; const month = item.startDate.split('-')[1]; const day = item.startDate.split('-')[2]; // 日期 // const date = new Date(year, month - 1, day); xAxisData.push(`${month}月${day}日`); seriesData.push(item.num); }); } else { if (period === 'week' && data) { data.forEach(item => { const year = item.startDate.split('-')[0]; const month = item.startDate.split('-')[1]; const day = item.startDate.split('-')[2]; const date = new Date(year, month - 1, day); xAxisData.push(`${date.getMonth() + 1}月${date.getDate()}日`); seriesData.push(item.num); }); } else if (period === 'month' && data) { data.forEach(item => { const year = item.startDate.split('-')[0]; const month = item.startDate.split('-')[1]; const day = item.startDate.split('-')[2]; xAxisData.push(`${day}日`); seriesData.push(item.num); }); } else if (period === 'year' && data) { data.forEach(item => { const year = item.startDate.split('-')[0]; const month = item.startDate.split('-')[1]; // 假设每月1号为数据点 const date = new Date(year, month - 1, 1); xAxisData.push(`${date.getMonth()+1}月`); seriesData.push(item.num); }); } } const option = { tooltip: { trigger: 'axis', }, xAxis: { type: 'category', data: xAxisData, // axisLine: { show: false }, // 隐藏X轴坐标轴线条 splitLine: { show: false }, // 隐藏X轴分割线 }, yAxis: { type: 'value', min: 0, // max: 100, axisLine: { show: false }, // 隐藏Y轴坐标轴线条 splitLine: { show: true, lineStyle: { type: 'dashed', color: '#e8e8e8', }, }, }, // 滑块组件 dataZoom: [ { type: 'slider', start: 0, end: 100, dataBackground: { lineStyle: { // color: 'white' }, areaStyle: { color: '#dedce0' } }, backgroundColor: '#ffffff', //组件的背景颜色 fillerColor: 'rgba(91, 143, 249, 0.15)' //选中范围的填充颜色 }, { type: 'inside', start: 50, end: 70 } ], series: [ { name: '扣分条数', type: 'bar', data: seriesData, itemStyle: { color: '#3ba1ff', }, }, ], }; myChart.setOption(option); },
这里对于后端返回的日期数据2024-10-25有两种处理方法:
1、直接切割数据后提取
data.forEach(item => { const year = item.startDate.split('-')[0]; const month = item.startDate.split('-')[1]; const day = item.startDate.split('-')[2]; xAxisData.push(`${month}月${day}日`); seriesData.push(item.num); });
2、Date()中的month是从0开始的
data.forEach(item => { const year = item.startDate.split('-')[0]; const month = item.startDate.split('-')[1]; const day = item.startDate.split('-')[2]; const date = new Date(year, month - 1, day); xAxisData.push(`${date.getMonth() + 1}月${date.getDate()}日`); seriesData.push(item.num); });