当前位置:首页 > JavaScript

js实现阿甘图可拖拽

2026-01-31 07:32:52JavaScript

实现阿甘图(Gantt Chart)可拖拽功能

使用JavaScript实现可拖拽的阿甘图需要结合HTML、CSS和JavaScript技术。以下是实现步骤:

HTML结构

<div id="gantt-container">
  <div class="gantt-task" data-task-id="1" style="left: 50px; width: 200px;">
    <div class="gantt-task-bar"></div>
    <div class="gantt-task-handle left"></div>
    <div class="gantt-task-handle right"></div>
  </div>
</div>

CSS样式

#gantt-container {
  position: relative;
  height: 500px;
  border: 1px solid #ccc;
  overflow-x: scroll;
}

.gantt-task {
  position: absolute;
  height: 30px;
  cursor: move;
}

.gantt-task-bar {
  height: 100%;
  background-color: #4CAF50;
  border-radius: 3px;
}

.gantt-task-handle {
  position: absolute;
  width: 8px;
  height: 100%;
  background-color: #333;
  cursor: ew-resize;
}

.gantt-task-handle.left {
  left: -4px;
}

.gantt-task-handle.right {
  right: -4px;
}

JavaScript实现

document.addEventListener('DOMContentLoaded', function() {
  const tasks = document.querySelectorAll('.gantt-task');

  tasks.forEach(task => {
    const bar = task.querySelector('.gantt-task-bar');
    const leftHandle = task.querySelector('.gantt-task-handle.left');
    const rightHandle = task.querySelector('.gantt-task-handle.right');

    let isDragging = false;
    let isResizingLeft = false;
    let isResizingRight = false;
    let startX, startLeft, startWidth;

    // 任务条拖动
    bar.addEventListener('mousedown', function(e) {
      isDragging = true;
      startX = e.clientX;
      startLeft = parseInt(task.style.left) || 0;
      e.preventDefault();
    });

    // 左侧调整大小
    leftHandle.addEventListener('mousedown', function(e) {
      isResizingLeft = true;
      startX = e.clientX;
      startLeft = parseInt(task.style.left) || 0;
      startWidth = parseInt(task.style.width) || 0;
      e.preventDefault();
    });

    // 右侧调整大小
    rightHandle.addEventListener('mousedown', function(e) {
      isResizingRight = true;
      startX = e.clientX;
      startWidth = parseInt(task.style.width) || 0;
      e.preventDefault();
    });

    document.addEventListener('mousemove', function(e) {
      if (!isDragging && !isResizingLeft && !isResizingRight) return;

      const dx = e.clientX - startX;

      if (isDragging) {
        const newLeft = startLeft + dx;
        task.style.left = `${newLeft}px`;
      }

      if (isResizingLeft) {
        const newLeft = startLeft + dx;
        const newWidth = startWidth - dx;

        if (newWidth > 30) { // 最小宽度限制
          task.style.left = `${newLeft}px`;
          task.style.width = `${newWidth}px`;
        }
      }

      if (isResizingRight) {
        const newWidth = startWidth + dx;

        if (newWidth > 30) { // 最小宽度限制
          task.style.width = `${newWidth}px`;
        }
      }
    });

    document.addEventListener('mouseup', function() {
      isDragging = false;
      isResizingLeft = false;
      isResizingRight = false;
    });
  });
});

功能扩展建议

  1. 时间轴同步 添加时间轴标尺并与任务位置同步,便于直观了解任务时间跨度。

  2. 数据绑定 将任务位置和尺寸与后台数据绑定,实现持久化存储:

    function saveTaskData(taskId, left, width) {
      // 保存到数据库或本地存储
    }
  3. 限制范围 添加容器边界检测,防止任务被拖出可视区域:

    const container = document.getElementById('gantt-container');
    const containerWidth = container.offsetWidth;
    
    // 在拖动和调整大小逻辑中添加边界检查
    if (newLeft < 0) newLeft = 0;
    if (newLeft + newWidth > containerWidth) newWidth = containerWidth - newLeft;
  4. 依赖关系 实现任务间的依赖关系连线,使用SVG或Canvas绘制连线。

  5. 性能优化 对于大量任务,考虑使用虚拟滚动技术只渲染可视区域内的任务。

使用现成库的替代方案

如果需要更完整的解决方案,可以考虑以下专门用于阿甘图的JavaScript库:

  1. dhtmlxGantt

    gantt.init("gantt_container");
    gantt.config.drag_move = true;
    gantt.config.drag_resize = true;
  2. Frappe Gantt

    const gantt = new Gantt("#gantt", tasks, {
      draggable: true,
      on_click: function(task) { ... },
      on_date_change: function(task, start, end) { ... }
    });
  3. jQuery Gantt

    $("#gantt").gantt({
      source: tasks,
      itemsPerPage: 10,
      draggable: true
    });

这些库提供了更丰富的功能,包括任务分组、关键路径分析、资源分配等高级特性。

js实现阿甘图可拖拽

标签: 阿甘拖拽
分享给朋友:

相关文章

vue实现拖拽div

vue实现拖拽div

Vue 实现拖拽 Div 的方法 使用原生 HTML5 拖拽 API HTML5 提供了原生的拖拽 API,结合 Vue 的事件绑定可以快速实现拖拽功能。以下是实现步骤: <template&…

vue实现模块拖拽

vue实现模块拖拽

Vue 实现模块拖拽的方法 使用 HTML5 原生拖拽 API HTML5 提供了原生拖拽 API,可以通过 draggable 属性、dragstart、dragend、dragover 和 dro…

前端实现拖拽功能vue

前端实现拖拽功能vue

使用 HTML5 拖放 API 在 Vue 中可以通过 HTML5 的原生拖放 API 实现拖拽功能。需要监听 dragstart、dragover 和 drop 事件。 <template…

vue 实现拖拽甘特图

vue 实现拖拽甘特图

实现拖拽甘特图的核心思路 Vue 实现拖拽甘特图需要结合第三方库或自定义逻辑,核心功能包括任务条渲染、时间轴刻度、拖拽交互、数据绑定等。以下是具体实现方法: 使用第三方库(推荐) vue-gan…

vue实现carousel拖拽

vue实现carousel拖拽

实现拖拽轮播的基本思路 在Vue中实现可拖拽的Carousel组件需要结合触摸事件(touchstart、touchmove、touchend)和鼠标事件(mousedown、mousemove、mo…

vue实现拖拽连线

vue实现拖拽连线

Vue 实现拖拽连线的方法 使用第三方库(推荐) 对于快速实现拖拽连线功能,推荐使用成熟的第三方库如 jsplumb 或 vue-draggable。这些库提供了丰富的 API 和事件支持,能够简化开…