记账微信小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

380 lines
9.0 KiB

// 引入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}`;
}
});
}
});