当前位置:首页 > 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

    js实现阿甘图可拖拽

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

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

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

相关文章

vue 实现拖拽甘特图

vue 实现拖拽甘特图

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

js实现图片拖拽

js实现图片拖拽

实现图片拖拽的基本步骤 HTML 结构需要包含可拖拽的图片元素,并设置 draggable 属性为 true: <img id="dragImage" src="image.jpg" drag…

vue实现拖拽事件

vue实现拖拽事件

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

vue实现tree拖拽

vue实现tree拖拽

Vue 实现 Tree 拖拽功能 使用 vue-draggable 库 vue-draggable 是基于 Sortable.js 的 Vue 拖拽组件库,适合实现树形结构的拖拽功能。 安装依赖:…

vue快速实现拖拽指令

vue快速实现拖拽指令

基础拖拽指令实现 通过v-drag指令实现元素拖拽功能,核心是利用鼠标事件和CSS变换: Vue.directive('drag', { inserted(el) { el.style.…

拖拽布局实现原理vue

拖拽布局实现原理vue

拖拽布局的实现原理 拖拽布局的核心是通过监听鼠标或触摸事件,动态调整元素的位置和尺寸。在Vue中,通常结合HTML5的拖拽API或第三方库(如vuedraggable)实现。 基本实现步骤 事件监听…