57 lines
2.0 KiB
JavaScript
57 lines
2.0 KiB
JavaScript
// Layout:布局计算器,负责任务条和依赖线的布局
|
||
export default class Layout {
|
||
constructor(tasks, config) {
|
||
this.tasks = tasks;
|
||
this.config = config;
|
||
}
|
||
// 计算任务条布局
|
||
computeTaskLayout() {
|
||
// 简单实现:每个任务一行,计算左侧(start)、宽度(end-start)
|
||
const layout = [];
|
||
this.tasks.forEach((task, idx) => {
|
||
const startPixel = this.dateToPixel(task.start);
|
||
const endPixel = this.dateToPixel(task.end);
|
||
layout.push({
|
||
id: task.id,
|
||
top: idx * 32,
|
||
left: startPixel,
|
||
width: endPixel - startPixel,
|
||
height: 28,
|
||
color: this.getTaskColor(task)
|
||
});
|
||
});
|
||
return layout;
|
||
}
|
||
// 计算依赖线布局(可扩展)
|
||
computeDependencyLines() {
|
||
// 返回依赖线的起止坐标
|
||
return [];
|
||
}
|
||
// 工具:日期转像素
|
||
dateToPixel(date) {
|
||
const start = new Date(this.config.startDate);
|
||
const d = new Date(date);
|
||
const scaleMap = { day: 40, week: 80, month: 200, quarter: 600 };
|
||
const scale = 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;
|
||
}
|
||
// 工具:获取任务颜色
|
||
getTaskColor(task) {
|
||
const group = this.config.groupBy;
|
||
if (group && task.dimensions && task.dimensions[group]) {
|
||
const id = task.dimensions[group].id;
|
||
return this.config.colors && this.config.colors[group] && this.config.colors[group][id] ? this.config.colors[group][id] : '#409EFF';
|
||
}
|
||
return '#409EFF';
|
||
}
|
||
}
|