// 引入wx-chart图表库 import WxChart from '../utils/wx-chart.js'; Page({ data: { // 当前时间类型:year, month, quarter currentTimeType: 'year', // 当前周期文本 currentPeriodText: '2023年', // 当前选中的饼图类型:income, expense currentPieType: 'income', // 收入总额 incomeTotal: '¥128,500.00', // 支出总额 expenseTotal: '¥85,300.00', // 当前选中的标签页 currentTab: 'statistics', // 饼图图例数据 currentPieLegend: [], // 图表实例 trendChart: null, categoryChart: null, // 时间数据 timeData: { year: { labels: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], income: [8500, 9200, 10500, 9800, 11200, 12500, 11800, 13200, 12800, 14500, 13800, 15200], expense: [6200, 5800, 6500, 7200, 6800, 7500, 8200, 7800, 8500, 7900, 8200, 8800], totalIncome: 128500, totalExpense: 85300 }, month: { labels: ['第1周', '第2周', '第3周', '第4周', '第5周'], income: [3200, 3800, 3500, 4200, 2800], expense: [2100, 2500, 1900, 2300, 1800], totalIncome: 17500, totalExpense: 10600 }, quarter: { labels: ['Q1', 'Q2', 'Q3', 'Q4'], income: [28200, 33500, 37800, 29000], expense: [18500, 21800, 24500, 20500], totalIncome: 128500, totalExpense: 85300 } }, // 分类数据 categoryData: { income: { categories: ['工资', '奖金', '投资收益', '兼职', '其他'], data: [80000, 20000, 15000, 10000, 3500], colors: [ 'rgba(59, 130, 246, 0.8)', 'rgba(59, 130, 246, 0.7)', 'rgba(59, 130, 246, 0.6)', 'rgba(59, 130, 246, 0.5)', 'rgba(59, 130, 246, 0.4)' ] }, expense: { categories: ['餐饮', '住房', '交通', '购物', '娱乐', '其他'], data: [25000, 30000, 8000, 12000, 5300, 5000], colors: [ 'rgba(239, 68, 68, 0.8)', 'rgba(239, 68, 68, 0.7)', 'rgba(239, 68, 68, 0.6)', 'rgba(239, 68, 68, 0.5)', 'rgba(239, 68, 68, 0.4)', 'rgba(239, 68, 68, 0.3)' ] } }, // 当前时间 currentDate: { year: 2023, month: 1, quarter: 1 } }, onLoad() { // 初始化图表 this.initCharts(); // 初始化饼图图例 this.updatePieLegend('income'); }, onReady() { // 页面渲染完成后执行 }, // 初始化图表 initCharts() { // 初始化趋势图 this.initTrendChart(); // 初始化饼图 this.initPieChart(); }, // 初始化趋势图 initTrendChart() { const ctx = wx.createCanvasContext('trendChart', this); const data = this.data.timeData[this.data.currentTimeType]; this.data.trendChart = new WxChart({ canvasId: 'trendChart', type: 'line', categories: data.labels, series: [ { name: '收入', data: data.income, color: '#3B82F6', format: function (val) { return '¥' + val.toFixed(0); } }, { name: '支出', data: data.expense, color: '#EF4444', format: function (val) { return '¥' + val.toFixed(0); } } ], yAxis: { title: '金额 (¥)', format: function (val) { return val.toLocaleString(); }, min: 0 }, xAxis: { disableGrid: true }, extra: { lineStyle: 'curve' } }); }, // 初始化饼图 initPieChart() { const ctx = wx.createCanvasContext('categoryChart', this); const data = this.data.categoryData[this.data.currentPieType]; this.data.categoryChart = new WxChart({ canvasId: 'categoryChart', type: 'pie', series: data.data, labels: data.categories, colors: data.colors, extra: { pie: { offsetAngle: -90, radius: 80 } }, format: function (val, name) { const total = data.data.reduce((a, b) => a + b, 0); const percentage = Math.round((val / total) * 100) + '%'; return `${name}: ¥${val.toLocaleString()} (${percentage})`; } }); }, // 切换时间类型 changeTimeType(e) { const type = e.currentTarget.dataset.type; if (this.data.currentTimeType === type) return; this.setData({ currentTimeType: type }, () => { // 更新时间周期显示 this.updatePeriodDisplay(); // 更新趋势图数据 this.updateTrendChart(); // 更新总额显示 this.updateTotalAmounts(); }); }, // 更新时间周期显示 updatePeriodDisplay() { const { year, month, quarter } = this.data.currentDate; let text = ''; switch (this.data.currentTimeType) { case 'year': text = `${year}年`; break; case 'month': text = `${year}年${month}月`; break; case 'quarter': text = `${year}年第${quarter}季度`; break; } this.setData({ currentPeriodText: text }); }, // 更新趋势图数据 updateTrendChart() { const data = this.data.timeData[this.data.currentTimeType]; this.data.trendChart.updateData({ categories: data.labels, series: [ { name: '收入', data: data.income }, { name: '支出', data: data.expense } ] }); }, // 更新总额显示 updateTotalAmounts() { const data = this.data.timeData[this.data.currentTimeType]; this.setData({ incomeTotal: this.formatCurrency(data.totalIncome), expenseTotal: this.formatCurrency(data.totalExpense) }); }, // 切换饼图类型 changePieType(e) { const type = e.currentTarget.dataset.type; if (this.data.currentPieType === type) return; this.setData({ currentPieType: type }, () => { // 更新饼图数据 this.updatePieChart(); // 更新饼图图例 this.updatePieLegend(type); }); }, // 更新饼图数据 updatePieChart() { const data = this.data.categoryData[this.data.currentPieType]; this.data.categoryChart.updateData({ series: data.data, labels: data.categories, colors: data.colors }); }, // 更新饼图图例 updatePieLegend(type) { const data = this.data.categoryData[type]; const total = data.data.reduce((a, b) => a + b, 0); const legend = []; data.categories.forEach((category, index) => { const value = data.data[index]; const percentage = Math.round((value / total) * 100) + '%'; legend.push({ name: category, value: this.formatCurrency(value), percent: percentage, color: data.colors[index] }); }); this.setData({ currentPieLegend: legend }); }, // 上一个周期 prevPeriod() { const { currentDate, currentTimeType } = this.data; const newDate = { ...currentDate }; switch (currentTimeType) { case 'year': newDate.year--; break; case 'month': newDate.month--; if (newDate.month < 1) { newDate.month = 12; newDate.year--; } break; case 'quarter': newDate.quarter--; if (newDate.quarter < 1) { newDate.quarter = 4; newDate.year--; } break; } this.setData({ currentDate: newDate }, () => { this.updatePeriodDisplay(); // 实际应用中这里应该根据新日期请求数据 }); }, // 下一个周期 nextPeriod() { const { currentDate, currentTimeType } = this.data; const newDate = { ...currentDate }; switch (currentTimeType) { case 'year': newDate.year++; break; case 'month': newDate.month++; if (newDate.month > 12) { newDate.month = 1; newDate.year++; } break; case 'quarter': newDate.quarter++; if (newDate.quarter > 4) { newDate.quarter = 1; newDate.year++; } break; } this.setData({ currentDate: newDate }, () => { this.updatePeriodDisplay(); // 实际应用中这里应该根据新日期请求数据 }); }, // 格式化货币 formatCurrency(value) { return '¥' + value.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }, // 趋势图点击事件 touchTrendChart(e) { this.data.trendChart.showToolTip(e, { format: function (item, category) { return `${category} ${item.name}: ${item.data}`; } }); }, // 饼图点击事件 touchPieChart(e) { this.data.categoryChart.showToolTip(e, { format: function (item, category) { return `${category}: ${item.data}`; } }); } });