Files
im-uniapp/components/Gantt/core/TimeCalculator.js
2025-07-16 14:23:42 +08:00

82 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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