js实现阿甘图可拖拽
实现阿甘图(Gantt Chart)可拖拽功能
使用HTML5 Drag and Drop API
HTML5原生提供了拖拽API,结合JavaScript可以轻松实现拖拽功能。创建一个基本的阿甘图结构,通过监听拖拽事件实现交互。
<div class="gantt-container">
<div class="gantt-task" draggable="true" id="task1">Task 1</div>
</div>
document.addEventListener('DOMContentLoaded', function() {
const task = document.getElementById('task1');
task.addEventListener('dragstart', function(e) {
e.dataTransfer.setData('text/plain', e.target.id);
});
document.querySelector('.gantt-container').addEventListener('dragover', function(e) {
e.preventDefault();
});
document.querySelector('.gantt-container').addEventListener('drop', function(e) {
e.preventDefault();
const id = e.dataTransfer.getData('text/plain');
const draggableElement = document.getElementById(id);
const dropzone = e.target.closest('.gantt-container');
if (dropzone) {
dropzone.appendChild(draggableElement);
draggableElement.style.left = e.clientX + 'px';
draggableElement.style.top = e.clientY + 'px';
}
});
});
使用第三方库(如dhtmlxGantt)
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" style="width:100%; height:500px;"></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-10-01", duration: 3 },
{ id: 2, text: "Task 2", start_date: "2023-10-05", duration: 4 }
]
});
自定义拖拽逻辑
如果需要更灵活的拖拽行为,可以结合鼠标事件(mousedown, mousemove, mouseup)实现自定义拖拽逻辑。

const task = document.getElementById('task1');
let isDragging = false;
let offsetX, offsetY;
task.addEventListener('mousedown', function(e) {
isDragging = true;
offsetX = e.clientX - task.getBoundingClientRect().left;
offsetY = e.clientY - task.getBoundingClientRect().top;
task.style.position = 'absolute';
});
document.addEventListener('mousemove', function(e) {
if (!isDragging) return;
task.style.left = (e.clientX - offsetX) + 'px';
task.style.top = (e.clientY - offsetY) + 'px';
});
document.addEventListener('mouseup', function() {
isDragging = false;
});
拖拽限制与边界检查
确保拖拽元素不会超出容器边界,增加边界检查逻辑。
document.addEventListener('mousemove', function(e) {
if (!isDragging) return;
const container = document.querySelector('.gantt-container');
const containerRect = container.getBoundingClientRect();
const taskRect = task.getBoundingClientRect();
let newX = e.clientX - offsetX;
let newY = e.clientY - offsetY;
newX = Math.max(containerRect.left, Math.min(newX, containerRect.right - taskRect.width));
newY = Math.max(containerRect.top, Math.min(newY, containerRect.bottom - taskRect.height));
task.style.left = (newX - containerRect.left) + 'px';
task.style.top = (newY - containerRect.top) + 'px';
});
拖拽事件与甘特图数据同步
拖拽后更新甘特图数据,确保UI与数据保持一致。
document.addEventListener('mouseup', function() {
if (!isDragging) return;
isDragging = false;
const taskId = task.id;
const newLeft = parseInt(task.style.left);
const newDuration = calculateNewDuration(newLeft); // 自定义计算新持续时间的函数
updateTaskInData(taskId, newLeft, newDuration); // 更新数据
});
通过以上方法,可以实现阿甘图的可拖拽功能,根据需求选择适合的实现方式。






