Files
im-uniapp/components/Gantt/core/TimeCalculator.js

82 lines
3.0 KiB
JavaScript
Raw Normal View History

2025-07-16 14:23:42 +08:00
// TimeCalculator时间轴计算器负责时间与像素的转换、生成时间刻度等
export default class TimeCalculator {
constructor(config) {
this.config = config;
this.scaleMap = { day: 40, week: 80, month: 200, quarter: 600 }; // 每单位像素宽度
}
// 日期转像素坐标
dateToPixel(date) {
const start = new Date(this.config.startDate);
const d = new Date(date);
const scale = this.scaleMap[this.config.timeScale] || 80;
let diff = 0;
if (this.config.timeScale === 'day') {
diff = (d - start) / (1000 * 3600 * 24);
} else if (this.config.timeScale === 'week') {
diff = (d - start) / (1000 * 3600 * 24 * 7);
} else if (this.config.timeScale === 'month') {
diff = (d.getFullYear() - start.getFullYear()) * 12 + (d.getMonth() - start.getMonth());
} else if (this.config.timeScale === 'quarter') {
diff = ((d.getFullYear() - start.getFullYear()) * 12 + (d.getMonth() - start.getMonth())) / 3;
}
return diff * scale;
}
// 像素转日期(仅简单实现,实际可扩展)
pixelToDate(pixel) {
const start = new Date(this.config.startDate);
const scale = this.scaleMap[this.config.timeScale] || 80;
let d = new Date(start);
if (this.config.timeScale === 'day') {
d.setDate(start.getDate() + pixel / scale);
} else if (this.config.timeScale === 'week') {
d.setDate(start.getDate() + (pixel / scale) * 7);
} else if (this.config.timeScale === 'month') {
d.setMonth(start.getMonth() + pixel / scale);
} else if (this.config.timeScale === 'quarter') {
d.setMonth(start.getMonth() + (pixel / scale) * 3);
}
return d;
}
// 生成时间轴刻度
getTimelineTicks() {
const ticks = [];
const start = new Date(this.config.startDate);
const end = new Date(this.config.endDate);
let cur = new Date(start);
while (cur <= end) {
ticks.push({
label: this.formatTick(cur),
date: new Date(cur)
});
if (this.config.timeScale === 'day') {
cur.setDate(cur.getDate() + 1);
} else if (this.config.timeScale === 'week') {
cur.setDate(cur.getDate() + 7);
} else if (this.config.timeScale === 'month') {
cur.setMonth(cur.getMonth() + 1);
} else if (this.config.timeScale === 'quarter') {
cur.setMonth(cur.getMonth() + 3);
}
}
return ticks;
}
// 格式化刻度
formatTick(date) {
if (this.config.timeScale === 'day') {
return date.toISOString().slice(5, 10);
} else if (this.config.timeScale === 'week') {
return 'W' + this.getWeekNumber(date);
} else if (this.config.timeScale === 'month') {
return date.getFullYear() + '-' + (date.getMonth() + 1);
} else if (this.config.timeScale === 'quarter') {
return date.getFullYear() + ' Q' + (Math.floor(date.getMonth() / 3) + 1);
}
return '';
}
// 获取周数
getWeekNumber(date) {
const firstDay = new Date(date.getFullYear(), 0, 1);
const dayOfYear = ((date - firstDay) / 86400000) + 1;
return Math.ceil(dayOfYear / 7);
}
}