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