js实现阿甘图可拖拽
实现阿甘图(Gantt Chart)可拖拽功能
阿甘图是一种项目管理工具,用于展示任务的时间安排和进度。实现可拖拽功能可以增强用户体验,允许用户调整任务的时间范围或顺序。以下是使用JavaScript实现可拖拽阿甘图的步骤。
使用HTML和CSS构建基础结构
创建一个基础的HTML结构,包含任务列表和时间轴。CSS用于样式化阿甘图的布局。
<div class="gantt-container">
<div class="gantt-header">
<div class="gantt-time-scale"></div>
</div>
<div class="gantt-body">
<div class="gantt-task" draggable="true">
<div class="gantt-task-bar"></div>
</div>
</div>
</div>
.gantt-container {
width: 100%;
overflow-x: auto;
}
.gantt-header {
display: flex;
border-bottom: 1px solid #ccc;
}
.gantt-time-scale {
display: flex;
min-width: 1000px;
}
.gantt-body {
position: relative;
height: 500px;
}
.gantt-task {
position: absolute;
height: 30px;
cursor: move;
}
.gantt-task-bar {
height: 100%;
background-color: #4CAF50;
border-radius: 3px;
}
添加拖拽事件监听
使用JavaScript为任务条添加拖拽事件监听,实现拖拽功能。
document.addEventListener('DOMContentLoaded', function() {
const tasks = document.querySelectorAll('.gantt-task');
tasks.forEach(task => {
task.addEventListener('dragstart', handleDragStart);
task.addEventListener('dragend', handleDragEnd);
});
const ganttBody = document.querySelector('.gantt-body');
ganttBody.addEventListener('dragover', handleDragOver);
ganttBody.addEventListener('drop', handleDrop);
});
function handleDragStart(e) {
e.dataTransfer.setData('text/plain', e.target.id);
e.target.classList.add('dragging');
}
function handleDragEnd(e) {
e.target.classList.remove('dragging');
}
function handleDragOver(e) {
e.preventDefault();
}
function handleDrop(e) {
e.preventDefault();
const taskId = e.dataTransfer.getData('text/plain');
const task = document.getElementById(taskId);
const ganttBody = e.currentTarget;
const rect = ganttBody.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
task.style.left = `${x}px`;
task.style.top = `${y}px`;
}
实现时间范围调整
拖拽任务条的边缘可以调整任务的时间范围。为任务条的左右边缘添加拖拽手柄。
<div class="gantt-task" draggable="true">
<div class="gantt-task-bar">
<div class="resize-handle left"></div>
<div class="resize-handle right"></div>
</div>
</div>
.resize-handle {
width: 5px;
height: 100%;
background-color: rgba(0, 0, 0, 0.2);
cursor: ew-resize;
}
.resize-handle.left {
float: left;
}
.resize-handle.right {
float: right;
}
document.querySelectorAll('.resize-handle').forEach(handle => {
handle.addEventListener('mousedown', initResize);
});
function initResize(e) {
const taskBar = e.target.parentElement;
const startX = e.clientX;
const startWidth = taskBar.offsetWidth;
function doResize(e) {
const newWidth = startWidth + (e.clientX - startX);
taskBar.style.width = `${newWidth}px`;
}
function stopResize() {
window.removeEventListener('mousemove', doResize);
window.removeEventListener('mouseup', stopResize);
}
window.addEventListener('mousemove', doResize);
window.addEventListener('mouseup', stopResize);
}
集成第三方库简化实现
使用现成的库如dhtmlxGantt可以快速实现可拖拽阿甘图。
<link rel="stylesheet" href="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css">
<script src="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
<div id="gantt_container"></div>
gantt.init('gantt_container');
gantt.config.drag_move = true;
gantt.config.drag_resize = true;
gantt.parse({
data: [
{ id: 1, text: 'Task 1', start_date: '2023-01-01', duration: 3 },
{ id: 2, text: 'Task 2', start_date: '2023-01-05', duration: 4 }
]
});
注意事项
- 拖拽功能需要兼容移动设备时,需添加触摸事件支持。
- 时间轴的刻度需要与任务的位置和宽度对应,确保拖拽后的时间计算准确。
- 对于复杂的项目需求,建议使用专业库如
dhtmlxGantt或frappe-gantt。






