React+dhtmlx实现甘特图

React+dhtmlx基础配置设置

前言

在现代企业生产管理系统中,甘特图是不可或缺的数据可视化工具,它能直观展示任务的时间安排、进度和依赖关系。本文将详细介绍如何在 React 项目中集成 dhtmlx-gantt 组件,实现功能丰富的生产排程甘特图。

环境介绍

本文采用 Vite + React + dhtmlx-gantt

javascript 复制代码
# 安装 dhtmlx-gantt 及其样式
npm install dhtmlx-gantt
npm install dhtmlx-gantt/codebase/dhtmlxgantt.css

遇到npm安装报错时,可以尝试切换数据源或改用yarn进行安装。

基础甘特图实现

javascript 复制代码
import React, { useRef, useEffect } from 'react';
import { gantt } from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';

const GanttChart = () => {
    const ganttContainer = useRef(null);

    useEffect(() => {
        if (ganttContainer.current) {
            // 列配置
            gantt.config.columns = [
                { name: "text", label: "任务名称", width: 200, tree: true },
                { name: "start_date", label: "开始时间", width: 100 },
                { name: "duration", label: "工期", width: 80 },
                { name: "progress", label: "进度", width: 80, template: gantt.templates.percent }
            ];

            // 初始化
            gantt.init(ganttContainer.current);

            // 加载数据
            const data = {
                data: [
                    { id: 1, text: "项目总计划", start_date: "2025-01-01", duration: 20, progress: 0.2 },
                    // parent指定父级数据 duration持续的天数  progress展示的百分比
                    { id: 2, text: "需求阶段", start_date: "2025-01-01", duration: 5, progress: 0.8, parent: 1 },
                    { id: 3, text: "设计阶段", start_date: "2025-01-06", duration: 6, progress: 0.4, parent: 1 },
                    { id: 4, text: "开发阶段", start_date: "2025-01-13", duration: 8, progress: 0.1, parent: 1 }
                ]
            };

            gantt.parse(data);
        }

        return () => {
            gantt.clearAll();
        };
    }, []);

    return (
        <div className="gantt-container">
            <div ref={ganttContainer} style={{ width: "100%", height: "400px" }}></div>
        </div>
    );
};

export default GanttChart;

简单的配置表格列和数据后,得到最初的效果

效果基本出来了,已经实现了树形数据的展示,以及点击表格行定位对应的甘特图的效果。

但是跟我预期的效果还有些差距。

需求完善

目前的问题

  1. 目前左右两个区域共享一个滚动条,只有右侧图表内容可以滚动。当表格项较多时,图表区域的显示空间会被大幅压缩。
  2. 时间线目前仅显示月份和日期,缺少年份信息。此外,月份默认仍采用英文格式显示。
  3. 在甘特图中,仅需显示色块部分,无需展示任务名称,同时不要显示进度百分比的颜色区分。

新增的需求

  1. 图表中需对周末列需要采用颜色区分
  2. 基于数据状态动态调整显示图表颜色
  3. 添加复选框实现可选并实现树形数据的上下级联动及全选/全不选功能

具体实现

自定义布局(左右分区)
javascript 复制代码
// 实现左右均分布局,并实现左右区域横向各自独立滚动,共享垂直滚动条
gantt.config.layout = {
    css: "gantt_container",
    cols: [
        {
            min_width: 400, // 避免左侧表格过度收缩
            rows: [
                {
                    group: "gantt",
                    cols: [
                        {
                            rows: [
                                { view: 'grid', scrollX: 'gridScrollX', scrollable: true, scrollY: 'gridScrollY' },
                                { view: 'scrollbar', id: 'gridScrollX' }
                            ]
                        }
                    ]
                },
            ]
        },
        { resizer: true, width: 1 },
        {
            rows: [
                {
                    group: "gantt",
                    cols: [
                        {
                            rows: [
                                { view: "timeline", scrollX: "scrollHor", scrollY: "gridScrollY" },
                                { view: "scrollbar", id: "scrollHor" }
                            ]
                        }
                    ]
                },
            ]
        },
        { view: 'scrollbar', id: 'gridScrollY' }
    ]
};

// 启用弹性列
gantt.config.grid_elastic_columns = true;
日期线设置
javascript 复制代码
gantt.config.date_format = "%Y-%m-%d";
// 日期分两行呈现: 上方显示年月 下方显示具体日期
gantt.config.scales = [
    { unit: "month", step: 1, format: "%Y年%F" },
    { unit: "day", step: 1, format: "%j日" }
];
// 优化月份与星期的本地化显示
gantt.locale = {
    date: {
        month_short: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
        month_full: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
        day_full: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
        day_short: ["日", "一", "二", "三", "四", "五", "六"]
    }
}

// 周末添加指定class
gantt.templates.timeline_cell_class = (task, date) => {
    if (date.getDay() === 0 || date.getDay() === 6) {
        return "weekend";
    }
    return "";
},
// 在css文件中添加高亮样式
.weekend {
    background-color: #f9f9f9 !important;
}

甘特图设置

javascript 复制代码
// 任务名称显示为空
task_text: () => '',
// 区分数据状态,设置相应的class
task_class: (start, end, task) => {
    switch(task.status) {
        case "未派发":
            return "wait-task";
        case "已派发":
            return "completed-task";
        default:
            return "";
    }
}
// 在css文件中设置样式
.wait-task {
    background-color: #ffa940 !important;
    border-color: #ffa940 !important;
}

.completed-task {
    background-color: #52c41a !important;
    border-color: #52c41a !important;
}

// 修改数据
// 1.通过status属性设置不同颜色样式
// 2.移除progress属性以隐藏百分比显示
const data = {
   data: [
        { id: 1, text: "项目总计划", status: '未派发', start_date: "2025-11-01", duration: 20 },
        { id: 2, text: "需求阶段", status: '已派发', start_date: "2025-01-01", duration: 5, parent: 1 },
        { id: 3, text: "设计阶段", status: '未派发', start_date: "2025-01-06", duration: 6, parent: 1 },
        { id: 4, text: "开发阶段", status: '已派发', start_date: "2025-01-13", duration: 8, parent: 1 }
    ],
};

结语

目前已经基本实现了预期效果。由于篇幅限制,复选框功能将在下次更新时介绍。如果不需要复选功能,希望本文内容可以帮到哪怕一位开发者。复选框的实现涉及dhtmlx-gantt与React的集成,主要包括事件处理和状态管理两部分内容,下一篇见!

相关推荐
小程故事多_8017 小时前
用Agent与大模型实现Web项目全自动化生成:从需求到部署的完整落地方案
运维·前端·人工智能·自动化·aigc
千里马-horse17 小时前
AsyncContext
开发语言·前端·javascript·c++·napi·asynccontext
勇往直前plus17 小时前
Jackson 反序列化首字母大写字段映射失败的底层原因与解决方案
java·开发语言·前端
转转技术团队17 小时前
基于微前端 qiankun 多实例保活的工程实践
前端·javascript·前端工程化
松涛和鸣17 小时前
37、UDP网络编程入门
linux·服务器·前端·网络·udp·php
毕设十刻17 小时前
基于Vue的新生入学报道管理系统(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
期待のcode17 小时前
JWT令牌
前端·javascript·spring boot·安全
JZXStudio17 小时前
Swift 6 + MLX + SwiftUI:三位一体本地AI架构蓝图
前端·ios
王金涛17 小时前
React 缺失的"M"层:我开发了 Zenith,把完整的 Model 带回了前端
react.js
神秘的猪头17 小时前
彻底搞懂 React 组件通信:从 TodoList 实战出发,解锁 React 开发的“核心姿势” 🚀
前端·react.js·架构