Dhtmlx Gantt教程:创建交互式甘特图的完整指南

news2024/11/15 21:45:53

在现代的项目管理中,时间是一种宝贵的资源,而甘特图则是一把解锁项目进度的魔法钥匙,想象一下,您可以在一个直观而动态的时间轴上,清晰地看到项目的每一个任务如何交织在一起,如何随着时间的推移展开,如何影响着项目的整体进度。这就是Dhtmlx Gantt带给我们的强大能力。

目录

初识Dhtmlx Gantt

Dhtmlx Gantt配置项 

Dhtmlx Gantt基础操作

多任务实现

初识Dhtmlx Gantt

Dhtmlx Gantt介绍:主要是用来创建和管理甘特图的工具库,甘特图是一种项目管理图表,通过条形图展示任务的开始时间、持续时间和完成进度,同时显示任务之间的依赖关系。Dhtmlx Gantt提供了丰富的功能和可定制选项,开发者可以轻松构建出功能强大、直观清晰的甘特图,用于项目计划和进度管理,从而使得用户可以灵活地配置和显示项目的时间轴、任务列表、资源分配情况等信息。这里我们可以阅读一下Dhtmlx Gantt的官网了解详细信息:地址 :

因为公司项目主要使用react技术栈,这里我们就拿该框架进行举例,参考文档:地址 :

插件安装:这里我们选择安装稳定版本(博主以稳定版本讲解)的,终端执行如下命令即可:

npm i dhtmlx-gantt

后面使用该插件的时候,直接导入包和对应的样式即可:

import { Gantt} from "dhtmlx-gantt";
import "dhtmlx-gantt/codebase/dhtmlxgantt.css";

当然也可以安装试用版本,和稳定版本有点区别,这里大家可自行去官网翻阅,这里不再赘述:

npm install @dhx/trial-gantt

如果您选择安装试用版,导入路径应如下所示:

import { Gantt} from "@dhx/trial-gantt";
import "@dhx/trial-gantt/codebase/dhtmlxgantt.css";

这里我们仿造官网给出的案例,如下给出先给出完整的代码进行基础演示:

import { useEffect, useRef } from 'react';
import { gantt } from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
import './index.less'

const data = {
    // 任务数据
    data: [
        {
            id: 1,
            text: 'projectName',
            start_date: '01-04-2023',
            end_date: '05-12-2023',
            progress: 0.3,
            value: 20,
        },
        {
            id: 2,
            text: '任务1',
            start_date: '02-04-2023',
            end_date: '11-07-2023',
            progress: 0.6,
            value: 20,

        },
        {
            id: 3,
            text: '任务211',
            start_date: '02-04-2023',
            end_date: '23-07-2023',
            progress: 0,
            value: 20,

        }
    ],
    // 任务连线数据
    links: [
        { id: 1, source: 1, target: 2, type: '1' },
        { id: 2, source: 2, target: 3, type: '0' }
    ]
};

// 左侧标题数据
const columns = [
    { name: 'text', label: '项目名称',  width: 100, align: "center" },
    { name: 'start_date', label: '开始时间', width: 100, align: "center" },
    { name: 'start_date', label: '开始时间', width: 100, align: "center" },
    { name: 'value', label: '计划工期', width: 100, align: "center" },
];

const GanttView = () => {
    // 获取gantrt容器实例
    const ganttRef = useRef<any>();
    // 初始化gantt
    const initGantt = () => {
        // 基础配置
        gantt.clearAll() // 清空之前的配置
        gantt.i18n.setLocale('cn'); // 设置中文
        gantt.config.readonly = true; // 设置为只读,否则是可以移动甘特图和连线的
        gantt.init(ganttRef.current); // 初始化甘特图
        gantt.parse(data); // 渲染数据
        gantt.config.order_branch = "marker";

        // 表头样式设置
        gantt.config.scale_height = 60; // 设置表头高度
        gantt.config.sort = true; // 点击表头可排序
        gantt.config.columns = columns; // 设置左侧表头数据
        gantt.config.scales = [ // 设置表头右侧刻度
            // 设置时间刻度相关属性
            // 显示月日用这个
            // { unit: 'month', step: 1, format: '%Y-%m' },
            // { unit: 'day', step: 1, format: '%Y-%m-%d' }
            // 显示年月用这个
            { unit: 'year', step: 1, format: '%Y' },
            { unit: 'month', step: 1, format: '%M' }
        ];

        // 表内容样式设置
        gantt.config.row_height = 40; // 设置内容行高
        gantt.config.bar_height = 40; // 设置进度条高度
        gantt.templates.task_text = function (start, end, task) { // 自定义内容进度上的文本
            return '内容'
        };
        // 表内容背景颜色
        gantt.templates.task_row_class = function (start, end, task) {
            return "gantt_task111";
        };

        // tooltips样式设置
        gantt.plugins({
            tooltip: true,
        });
        gantt.config.tooltip_offset_x = 10; 
        gantt.config.tooltip_offset_y = 30;
        gantt.templates.tooltip_text = function (start, end, task) {
            return (
                task.text +
                '<br/><span>开始:</span> ' +
                gantt.templates.tooltip_date_format(start) +
                '<br/><span>结束:</span> ' +
                gantt.templates.tooltip_date_format(end) +
                '<br/><span>进度:</span> ' +
                // Math.round(task.progress * 100) +
                '%'
            );
        };

        // 设置连线事件
        gantt.config.show_links = true;
    }

    useEffect(() => {
        initGantt();
    }, []);

    return (
        <div className="ganttView">
            <div className='ganttContainer' ref={ganttRef}></div>
        </div>
    )
};
export default GanttView;

最终得到的效果如下所示: 

Dhtmlx Gantt配置项 

接下来开始对配置项进行一个简单的介绍,如下所示:

数据配置项:甘特图中表头标题和表内容中的数据

任务数据data:在任务数据中里面对象的配置项有各种属性值,接下来就常用的属性值介绍:

/*
gantt.parse 方法中的 data 参数是一个包含任务信息的数组。每个任务都包含多个字段,下面是一些常用的字段及其作用:
id: 任务的唯一标识符。
text: 任务的名称。
start_date: 任务的开始日期,可以是一个字符串或者一个 Date 对象。
end_date: 任务的结束日期,可以是一个字符串或者一个 Date 对象。
duration: 任务的持续时间,以天为单位。如果 end_date 和 duration 都提供了,duration 会被忽略。
progress: 任务的进度,以百分比表示。
parent: 父任务的 id,如果当前任务是顶级任务,则该字段为 0。
open: 是否展开当前任务的子任务。如果不提供,默认为 true。
state: 用于设置任务的状态。状态可以是任何自定义值,例如 "in progress"、"completed"、"cancelled" 等等。在 Gantt 图中,任务的状态可以通过任务条颜色、边框、文本样式等 visulization 属性进行自定义渲染,以便用户更直观地了解任务状态的变化。可以在 Gantt 文档中的 Visualization 属性部分了解有关自定义任务状态可视化的更多信息。
除了上面列出的常用字段之外,还有很多其他可选字段,例如 color、link、type 等,可以根据实际需求来添加。
*/

const data = [
  { id: 1, text: "Task 1", start_date: "2023-03-15", duration: 3 },
  { id: 2, text: "Task 2", start_date: "2023-03-18", duration: 2, parent: 1 },
];

links数组:链接数据数组,包含每个链接的信息,例如 id、source、target 等等。

// 任务连线数据
links: [
    { id: 1, source: 1, target: 2, type: '1' },
    { id: 2, source: 2, target: 3, type: '0' }
]

当然还有一些其他常见的配置项这里就不再一一赘述了,如下:

key: 任务数据对象中唯一标识每个任务的属性名称,默认为 "id"。
parent: 任务数据对象中用于标识父任务的属性名称,默认为 "parent".
open_tree_initially: 布尔值,如果设置为 true,则所有任务默认展开。
preserve_links: 布尔值,如果设置为 true,则链接信息中的任务不存在时也会保留链接。
preserve_tasks: 布尔值,如果设置为 true,则链接信息中的任务不存在时也会保留任务。

基础配置项:初始化甘特图时要进行的基础配置

gantt.clearAll() // 清空之前的配置
gantt.i18n.setLocale('cn'); // 设置中文
gantt.config.readonly = true; // 设置为只读,否则是可以移动甘特图和连线的
gantt.init(ganttRef.current); // 初始化甘特图
gantt.parse(data); // 渲染数据

表头样式配置项:对表头标题进行样式配置

// 甘特图样式设置
gantt.config.scale_height = 60; // 设置表头高度
// 设置头部左侧表头标题背景颜色
gantt.templates.grid_header_class = function (date, scale) {
    return "gantt_grid_head111";
};
// 设置左侧标题表内容背景颜色
gantt.templates.grid_row_class = function (date, scale) {
    return "gantt_scale_cell111";
};
// 设置头部右侧上标题内容背景颜色
gantt.templates.scale_cell_class = function (scale) {
    return "gantt_grid_head111";
};
// 设置头部右侧下标题内容背景颜色
gantt.templates.scale_row_class = function (scale) {
    return "gantt_grid_head111";
};
// 设置表主内容背景颜色
gantt.templates.task_row_class = function (start, end, task) {
    return "gantt_task111";
};
gantt.config.sort = true; // 设置点击左侧表头可排序
gantt.config.columns = columns; // 设置左侧表头数据
gantt.config.scales = [ // 设置表头右侧刻度
    // 设置时间刻度相关属性
    // 显示月日用这个
    // { unit: 'month', step: 1, format: '%Y-%m' },
    // { unit: 'day', step: 1, format: '%Y-%m-%d' }
    // 显示年月用这个
    { unit: 'year', step: 1, format: '%Y' },
    { unit: 'month', step: 1, format: '%M' }
];

表内容样式配置项:对表内容进行样式配置 

// 表内容样式设置
gantt.config.row_height = 40; // 设置内容行高
gantt.config.bar_height = 40; // 设置进度条高度
gantt.templates.task_text = function (start, end, task) { // 自定义内容进度上的文本
    return '内容'
};

悬浮框样式配置项:对表悬浮框进行样式配置

// tooltips样式设置
gantt.plugins({
    tooltip: true,
    // quick_info: true, // 快速信息框
    // multiselect: true,// 激活多任务选择
});
gantt.config.tooltip_offset_x = 10; // 设置tooltips水平偏移量
gantt.config.tooltip_offset_y = 30; // 设置tooltips垂直偏移量
gantt.templates.tooltip_text = function (start, end, task) {
    return (
        task.text +
        '<br/><span>开始:</span> ' +
        gantt.templates.tooltip_date_format(start) +
        '<br/><span>结束:</span> ' +
        gantt.templates.tooltip_date_format(end) +
        '<br/><span>进度:</span> ' +
        // Math.round(task.progress * 100) +
        '%'
    );
};

Dhtmlx Gantt基础操作

接下来复现一下一个甘特图的效果,这里我们给出书写甘特图的流程书写:

初始化甘特图:首先我们创建甘特图的容器,然后进行一些初始配置:

import { useEffect, useRef } from 'react';
import { gantt } from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';

const GanttView = () => {
    // 获取gantrt容器实例
    const ganttRef = useRef<any>();
    // 初始化gantt
    const initGantt = () => {
        gantt.clearAll() // 清空之前的配置
        gantt.i18n.setLocale('cn'); // 设置中文
        gantt.config.readonly = true; // 设置为只读,否则是可以移动甘特图和连线的
        gantt.init(ganttRef.current); // 初始化甘特图
        gantt.parse(data); // 渲染数据
    }

    useEffect(() => {
        initGantt();
    }, []);

    return (
        <div className="ganttView">
            <div className='ganttContainer' ref={ganttRef}></div>
        </div>
    )
};
export default GanttView;

给出表头数据:接下来开始创建表头数据:

const data = {
    data: [ // 任务数据
        { id: 1, text: '任务1', start_date: '01-04-2023', end_date: '05-12-2023', progress: 0.3 },
        { id: 2, text: '任务1', start_date: '02-04-2023', end_date: '11-07-2023', progress: 0.6 },
        { id: 3, text: '任务3', start_date: '12-07-2023', end_date: '09-09-2023', progress: 0 }
    ],
    links: [ // 任务连线数据
        { id: 1, source: 1, target: 2, type: '1' },
        { id: 2, source: 2, target: 3, type: '0' }
    ]
};

const columns = [ // 左侧标题数据
    { name: 'text', label: '项目名称',  width: 100, align: "center" },
    { name: 'start_date', label: '开始时间', width: 100, align: "center" },
    { name: 'end_date', label: '结束时间', width: 100, align: "center" },
];

样式配置:接下来给甘特图设置相关样式:

const initGantt = () => {
    // 基础配置
    gantt.clearAll() // 清空之前的配置
    gantt.i18n.setLocale('cn'); // 设置中文
    gantt.config.readonly = false; // 设置为只读,否则是可以移动甘特图和连线的
    gantt.init(ganttRef.current); // 初始化甘特图
    gantt.parse(data); // 渲染数据

    // 甘特图样式设置
    gantt.config.scale_height = 60; // 设置表头高度
    // 设置头部左侧表头标题背景颜色
    gantt.templates.grid_header_class = function (date, scale) {
        return "gantt_grid_head111";
    };
    // 设置左侧标题表内容背景颜色
    gantt.templates.grid_row_class = function (date, scale) {
        return "gantt_scale_cell111";
    };
    // 设置头部右侧上标题内容背景颜色
    gantt.templates.scale_cell_class = function (scale) {
        return "gantt_grid_head111";
    };
    // 设置头部右侧下标题内容背景颜色
    gantt.templates.scale_row_class = function (scale) {
        return "gantt_grid_head111";
    };
    // 设置表主内容背景颜色
    gantt.templates.task_row_class = function (start, end, task) {
        return "gantt_task111";
    };
    gantt.config.sort = true; // 设置点击左侧表头可排序
    gantt.config.columns = columns; // 设置左侧表头数据
    gantt.config.scales = [ // 设置表头右侧刻度
        // 设置时间刻度相关属性
        // 显示月日用这个
        // { unit: 'month', step: 1, format: '%Y-%m' },
        // { unit: 'day', step: 1, format: '%Y-%m-%d' }
        // 显示年月用这个
        { unit: 'year', step: 1, format: '%Y' },
        { unit: 'month', step: 1, format: '%M' }
    ];

    // 表内容样式设置
    gantt.config.row_height = 40; // 设置内容行高
    gantt.config.bar_height = 40; // 设置进度条高度
    gantt.templates.task_text = function (start, end, task) { // 自定义内容进度上的文本
        return '内容'
    };

    // tooltips样式设置
    gantt.plugins({ tooltip: true });
    gantt.config.tooltip_offset_x = 10; // 设置tooltips水平偏移量
    gantt.config.tooltip_offset_y = 30; // 设置tooltips垂直偏移量
    gantt.templates.tooltip_text = function (start, end, task: any) {
        return (
            task.text +
            '<br/><span>开始:</span> ' +
            gantt.templates.tooltip_date_format(start) +
            '<br/><span>结束:</span> ' +
            gantt.templates.tooltip_date_format(end) +
            '<br/><span>进度:</span> ' +
            Math.round(task.progress * 100) +
            '%'
        );
    };

    // 设置连线事件
    gantt.config.show_links = true;
    gantt.config.drag_project = true;
}

最终呈现的效果如下所示:

多任务实现

如果想在同一个x轴显示多条任务,需要配置分组,每组的子任务通过parent属性进行联系主任务,这里通过如下代码进行演示:

const data = {
    // 任务数据
    data: [
        //第一组 整条数据需要带上render属性  里面多段的数据parent执行整条的id
        { id: '1', name: '张三', render: 'split',  text: '' },
        { id: '1-1', parent: 1, text: '派工', color: '#008c8c', start_date: '15-06-2024 08:30', end_date: '15-06-2024: 10:30' },
        { id: '1-2', parent: 1, text: '休息', color: 'blue', start_date: '16-06-2024: 13:00', end_date: '16-06-2024:23:00' },
        
        // 第二组
        { id: '2', name: '李四', render: 'split', text: '' },
        { id: '2-1', parent: 2, text: '派工', color: '#008c8c', start_date: '15-06-2024 18:30', end_date: '15-06-2024: 22:30' },
        { id: '2-2', parent: 2, text: '休息', color: 'blue', start_date: '16-06-2024: 13:00', end_date: '16-06-2024:23:00' },

        // 第三组
        { id: '3', name: '王五', render: 'split', text: '' },
        { id: '3-1', parent: 3, text: '派工', color: '#008c8c', start_date: '15-06-2024 8:30', end_date: '15-06-2024: 22:30' },
        { id: '3-2', parent: 3, text: '休息', color: 'blue', start_date: '16-06-2024: 13:00', end_date: '16-06-2024:23:00' },
        { id: '3-3', parent: 3, text: '休息', color: 'blue', start_date: '16-06-2024: 13:00', end_date: '17-06-2024:3:00' },
        { id: '3-4', parent: 3, text: '派工', color: '#008c8c', start_date: '17-06-2024:2:00', end_date: '17-06-2024: 8:00' }
    ],
};

如果想在同一时段实现多任务,当前组件库好像实现不了,至少博主查阅了一下午的文档没找到,然后这里我通过css样式来进行控制其高度,然后通过判断任务之间的时段是否重叠进行动态添加类名,具体代码如下:

import { useEffect, useRef } from 'react';
import { gantt } from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
import './index.less'

const data = {
    // 任务数据
    data: [
        //第一组 整条数据需要带上render属性  里面多段的数据parent执行整条的id
        { id: '1', name: '张三', render: 'split',  text: '' },
        { id: '1-1', parent: 1, text: '派工', color: '#008c8c', start_date: '15-06-2024 08:30', end_date: '15-06-2024: 10:30' },
        { id: '1-2', parent: 1, text: '休息', color: 'blue', start_date: '16-06-2024: 13:00', end_date: '16-06-2024:23:00' },
        
        // 第二组
        { id: '2', name: '李四', render: 'split', text: '' },
        { id: '2-1', parent: 2, text: '派工', color: '#008c8c', start_date: '15-06-2024 18:30', end_date: '15-06-2024: 22:30' },
        { id: '2-2', parent: 2, text: '休息', color: 'blue', start_date: '16-06-2024: 13:00', end_date: '16-06-2024:23:00' },

        // 第三组
        { id: '3', name: '王五', render: 'split', text: '' },
        { id: '3-1', parent: 3, text: '派工', color: '#008c8c', start_date: '15-06-2024 8:30', end_date: '15-06-2024: 22:30' },
        { id: '3-2', parent: 3, text: '休息', color: 'blue', start_date: '16-06-2024: 13:00', end_date: '16-06-2024:23:00' },
        { id: '3-3', parent: 3, text: '休息', color: 'blue', start_date: '16-06-2024: 13:00', end_date: '17-06-2024:3:00' },
        { id: '3-4', parent: 3, text: '派工', color: '#008c8c', start_date: '17-06-2024:2:00', end_date: '17-06-2024: 8:00' },
        // { id: '3-4', parent: 3, text: '派工', color: '#008c8c', start_date: '16-06-2024:12:00', end_date: '17-06-2024: 8:00' },
    ],
};

// 左侧标题数据
const columns = [
    { name: 'id', label: '序号', resize: true,  max_width: 60, align: "center" },
    { name: 'name', label: '姓名', resize: true, max_width: 60, align: "center" },
];

const GanttView = () => {
    // 获取gantrt容器实例
    const ganttRef = useRef<any>();
    // 初始化gantt
    const initGantt = () => {
        gantt.clearAll() // 清空之前的配置
        gantt.i18n.setLocale('cn'); // 设置中文
        gantt.config.readonly = true; // 设置为只读,否则是可以移动甘特图和连线的
        gantt.config.start_date = new Date(2024, 5, 15); // 设置甘特图开始日期  
        gantt.config.end_date = new Date(2024, 5, 18); // 设置甘特图结束日期  
        gantt.init(ganttRef.current); // 初始化甘特图
        gantt.parse(data); // 渲染数据

        gantt.config.columns = columns; // 设置左侧表头数据
        gantt.config.scale_height = 60; // 设置表头高度
        gantt.config.min_column_width = 10; // 设置列最小宽度
        // 设置头部右侧上标题内容背景颜色
        gantt.templates.scale_cell_class = function (scale) {
            return "gantt_grid_head_top";
        };

        gantt.config.scales = [ // 设置甘特图时间轴
            { unit: 'day', step: 1, format: '%Y/%m/%d' },
            { unit: 'hour', step: 1, format: function(date) {  
                return date.getHours(); // 显示从0到23的小时范围  
            }}  
        ];
        
        // 表内容样式设置
        gantt.templates.task_row_class = function (start, end, task) { // 设置表主内容背景颜色
            return "gantt_task_main_content";
        };
        gantt.config.row_height = 40; // 设置内容行高
        gantt.config.bar_height = 40; // 设置进度条高度
        gantt.templates.task_text = function (start, end, task) {
            return `<div style="color: #fff; font-size: 12px;">${task?.text}</div>`;
        };
        let count = 0
        gantt.templates.task_class = function(start, end, task) {  
            if (count < 1) {
                // 创建一个空对象来存储结果
                let tasksByParent: { [key: string]: any[] } = {}; // 创建空对象来存储任务按父任务分组的结果
                // 遍历任务数组
                data.data.forEach((task) => {
                    if (task.parent) {
                        // 检查是否已经存在该parent对应的数组,如果不存在则创建一个空数组
                        if (!tasksByParent[task.parent]) {
                            tasksByParent[task.parent] = [];
                        }
                        // 将当前任务对象添加到对应parent值的数组中
                        tasksByParent[task.parent].push(task);
                    }
            
                });

                // 检查时间重叠并添加类名
                Object.keys(tasksByParent).forEach(parentId => {
                    let tasks = tasksByParent[parentId];
                    for (let i = 0; i < tasks.length; i++) {
                        for (let j = i + 1; j < tasks.length; j++) {
                            if (tasksOverlap(tasks[i], tasks[j])) {
                                tasks[i].className = (i % 2 === 0) ? 'custom-height-top2' : 'custom-height-bottom2';
                                tasks[j].className = (j % 2 === 0) ? 'custom-height-top2' : 'custom-height-bottom2';
                            }
                        }
                    }

                    for (let i = 0; i < tasks.length; i++) {
                        for (let j = i + 1; j < tasks.length; j++) {
                            for (let k = j + 1; k < tasks.length; k++) {
                                if (tasksOverlap(tasks[i], tasks[j]) && tasksOverlap(tasks[i], tasks[k]) && tasksOverlap(tasks[j], tasks[k])) {
                                    // 为每个重叠任务分配不同的类名
                                    tasks[i].className = 'custom-height-top3';
                                    tasks[j].className = 'custom-height-bottom3';
                                    tasks[k].className = 'custom-height-center3';
                                }
                            }
                        }
                    }
                    
                });
                console.log(tasksByParent);
                count++;
            }
            return task.className || ""; // 返回任务的类名,如果没有类名则返回空字符串
        };  

        // 检查两个任务时间段是否有重叠
        function tasksOverlap(task1: any, task2: any) {
            return (task1.start_date < task2.end_date && task2.start_date < task1.end_date);
        }
        // tooltips样式设置
        gantt.plugins({ tooltip: true });
        gantt.config.tooltip_offset_x = 10; // 设置tooltips水平偏移量
        gantt.config.tooltip_offset_y = 30; // 设置tooltips垂直偏移量
        gantt.templates.tooltip_text = function (start: Date, end: Date, task: any): string {
            if (task.text) {
                return (
                    `<div class="gantt-tooltip">
                        <div class="gantt-tooltip-time">
                            <div class="time-word">当前时间:</div>
                            <div class="time-value">
                                <div class="time-value-content"><span>开始时间:</span>${start.toLocaleString()}</div>
                                <div class="time-value-content"><span>结束时间:</span>${end.toLocaleString()}</div>
                            </div>
                        </div>
                        <div class="gantt-tooltip-task">
                            <div class="task-word">当前任务:</div>
                            <div class="task-value">${task.text}</div>
                        </div>
                    </div>`
                );
            }
            return "";
        };
    }

    useEffect(() => {
        initGantt();
    }, []);

    return (
        <div className="ganttView">
            <div className='ganttContainer' ref={ganttRef} style={{ width: '100%' }}></div>
        </div>
    )
};
export default GanttView;

上述代码我通过for循环来判断,识别当前是双任务还是三任务的时间进行了重叠,这里给出具体的css样式:

.ganttView {
    width: 100%;
    height: 250px;
    .ganttContainer {
        width: 100vw;
        overflow: hidden;
        height: 100%;
        // 设置左侧头部数据
        .gantt_grid_scale {
            background-color: #dce8ee;
            .gantt_grid_head_cell {
                font-size: 14px;
                font-weight: bold;
                color: #000;
            }
        }
        // 设置右侧头部数据
        .gantt_task_scale {
            background-color: #dce8ee;
            .gantt_grid_head_top {
                font-size: 14px !important;
                font-weight: bold;
                color: #000;
            }
            .gantt_scale_cell {
                font-size: 10px;
                font-weight: bold;
                color: #000;
            }
 
        }
        .gantt_task_main_content {
            background-color: #57ce7d;
        }
        
         // 去除表格单元格的竖线  
        .gantt_task_cell,  
        .gantt_task_cell.gantt_cell {  
            border-right: none !important;
        }  
        // 保留左侧标题单元格的竖线  
        .gantt_grid_head_cell,  
        .gantt_grid_data .gantt_cell {  
            border-right: 1px solid #dcdcdc !important; 
        }  
        /* 去除左侧标题和右侧表格内容的激活状态样式 */  
        .gantt_grid_data, .gantt_row.gantt_selected {
            background-color: transparent !important;
        }
     
        // 去除左侧标题内容的悬停效果
        .gantt_row:hover {
            background: none !important; // 去除背景色  
        }
        .gantt_row:active {
            background: none !important; // 去除背景色  
        }

        .custom-height-top2 {
            height: 20px !important; /* 设置特定任务条的高度 */  
            line-height: 20px !important; /* 调整行高以垂直居中文本 */  
        }
        .custom-height-bottom2 {
            height: 20px !important; /* 设置特定任务条的高度 */  
            line-height: 20px !important; /* 调整行高以垂直居中文本 */  
            margin-top: 20px;
        }
        .custom-height-top3 {
            height: 13.3px !important; /* 设置特定任务条的高度 */  
            line-height: 13.3px !important; /* 调整行高以垂直居中文本 */  
        }
        .custom-height-center3 {
            height: 13.3px !important; /* 设置特定任务条的高度 */  
            line-height: 13.3px !important; /* 调整行高以垂直居中文本 */  
            margin-top: 13.3px;
        }
        .custom-height-bottom3 {
            margin-top: 26.6px;
            height: 13.3px !important; /* 设置特定任务条的高度 */  
            line-height: 13.3px !important; /* 调整行高以垂直居中文本 */  
        }
    }
}

// tooltips样式
.gantt_tooltip {
    background-color: #ccc;
    .gantt-tooltip-time {
        display: flex;
        flex-direction: column;
        gap: 4px;
        margin-bottom: 4px;
        .time-word {
            color: #000;
            font-size: 12px;
            font-weight: bold;
        }
        .time-value {
            display: flex;
            flex-direction: column;
            gap: 2px;
            span {
                font-weight: bold;
            }
        }
    }
    .gantt-tooltip-task {
        display: flex;
        align-items: center;
        .task-word {
            color: #000;
            font-size: 12px;
            font-weight: bold;
        }
        .task-value {
            color: red;
        }
    }
}

当然还有单个任务的展示:

import { useEffect, useRef } from 'react';
import { gantt } from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
import './index.less'

const data = {
    // 任务数据
    data: [
        //第一组 整条数据需要带上render属性  里面多段的数据parent执行整条的id
        { id: '1', name: '张三', render: 'split',  text: '' },
        { id: '1-1', parent: 1, text: '工', color: 'blue', start_date: '14-06-2024', duration: 1 },
        { id: '1-2', parent: 1, text: '工', color: 'blue', start_date: '15-06-2024', duration: 1 },
        { id: '1-3', parent: 1, text: '工', color: 'blue', start_date: '16-06-2024', duration: 1 },
        { id: '1-4', parent: 1, text: '工', color: 'blue', start_date: '17-06-2024', duration: 1 },
        { id: '1-5', parent: 1, text: '工', color: 'blue', start_date: '18-06-2024', duration: 1 },
        { id: '1-6', parent: 1, text: '工', color: 'blue', start_date: '19-06-2024', duration: 1 },
        { id: '1-7', parent: 1, text: '年', color: 'red', start_date: '20-06-2024', duration: 1 },
        { id: '1-8', parent: 1, text: '闲', color: 'green', start_date: '21-06-2024', duration: 1 },
        { id: '1-9', parent: 1, text: '工', color: 'blue', start_date: '22-06-2024', duration: 1 },
        { id: '1-10', parent: 1, text: '工', color: 'blue', start_date: '23-06-2024', duration: 1 },
        { id: '1-11', parent: 1, text: '工', color: 'blue', start_date: '24-06-2024', duration: 1 },
        { id: '1-12', parent: 1, text: '工', color: 'blue', start_date: '25-06-2024', duration: 1 },
        { id: '1-13', parent: 1, text: '工', color: 'blue', start_date: '26-06-2024', duration: 1 },
        { id: '1-14', parent: 1, text: '工', color: 'blue', start_date: '27-06-2024', duration: 1 },
        { id: '1-15', parent: 1, text: '工', color: 'blue', start_date: '28-06-2024', duration: 1 },
        { id: '1-16', parent: 1, text: '工', color: 'blue', start_date: '29-06-2024', duration: 1 },
        { id: '1-17', parent: 1, text: '闲', color: 'green', start_date: '30-06-2024', duration: 1 },
        { id: '1-18', parent: 1, text: '闲', color: 'green', start_date: '1-07-2024', duration: 1 },
        { id: '1-19', parent: 1, text: '工', color: 'blue', start_date: '2-07-2024', duration: 1 },
        { id: '1-20', parent: 1, text: '工', color: 'blue', start_date: '3-07-2024', duration: 1 },
        { id: '1-21', parent: 1, text: '工', color: 'blue', start_date: '4-07-2024', duration: 1 },
        { id: '1-22', parent: 1, text: '工', color: 'blue', start_date: '5-07-2024', duration: 1 },
        { id: '1-23', parent: 1, text: '工', color: 'blue', start_date: '6-07-2024', duration: 1 },
        { id: '1-24', parent: 1, text: '工', color: 'blue', start_date: '7-07-2024', duration: 1 },
        { id: '1-25', parent: 1, text: '工', color: 'blue', start_date: '8-07-2024', duration: 1 },
        { id: '1-26', parent: 1, text: '工', color: 'blue', start_date: '9-07-2024', duration: 1 },
        { id: '1-27', parent: 1, text: '工', color: 'blue', start_date: '10-07-2024', duration: 1 },
        { id: '1-28', parent: 1, text: '工', color: 'blue', start_date: '11-07-2024', duration: 1 },
        { id: '1-29', parent: 1, text: '工', color: 'blue', start_date: '12-07-2024', duration: 1 },
        { id: '1-30', parent: 1, text: '工', color: 'red', start_date: '13-07-2024', duration: 1 },
        
        // 第二组
        { id: '2', name: '李四', render: 'split', text: '' },
        { id: '2-1', parent: 2, text: '工', color: 'blue', start_date: '14-06-2024', duration: 1 },
        { id: '2-2', parent: 2, text: '工', color: 'blue', start_date: '15-06-2024', duration: 1 },
        { id: '2-3', parent: 2, text: '工', color: 'blue', start_date: '16-06-2024', duration: 1 },
        { id: '2-4', parent: 2, text: '工', color: 'blue', start_date: '17-06-2024', duration: 1 },
        { id: '2-5', parent: 2, text: '工', color: 'blue', start_date: '18-06-2024', duration: 1 },
        { id: '2-6', parent: 2, text: '工', color: 'blue', start_date: '19-06-2024', duration: 1 },
        { id: '2-7', parent: 2, text: '工', color: 'blue', start_date: '20-06-2024', duration: 1 },
        { id: '2-8', parent: 2, text: '工', color: 'blue', start_date: '21-06-2024', duration: 1 },
        { id: '2-9', parent: 2, text: '工', color: 'blue', start_date: '22-06-2024', duration: 1 },
        { id: '2-10', parent: 2, text: '工', color: 'blue', start_date: '23-06-2024', duration: 1 },
        { id: '2-11', parent: 2, text: '工', color: 'blue', start_date: '24-06-2024', duration: 1 },
        { id: '2-12', parent: 2, text: '工', color: 'blue', start_date: '25-06-2024', duration: 1 },
        { id: '2-13', parent: 2, text: '工', color: 'blue', start_date: '26-06-2024', duration: 1 },
        { id: '2-14', parent: 2, text: '工', color: 'blue', start_date: '27-06-2024', duration: 1 },
        { id: '2-15', parent: 2, text: '工', color: 'blue', start_date: '28-06-2024', duration: 1 },
        { id: '2-16', parent: 2, text: '工', color: 'blue', start_date: '29-06-2024', duration: 1 },
        { id: '2-17', parent: 2, text: '工', color: 'blue', start_date: '30-06-2024', duration: 1 },
        { id: '2-18', parent: 2, text: '工', color: 'blue', start_date: '01-07-2024', duration: 1 },
        { id: '2-19', parent: 2, text: '工', color: 'blue', start_date: '02-07-2024', duration: 1 },
        { id: '2-20', parent: 2, text: '工', color: 'blue', start_date: '03-07-2024', duration: 1 },
        { id: '2-21', parent: 2, text: '工', color: 'blue', start_date: '04-07-2024', duration: 1 },
        { id: '2-22', parent: 2, text: '工', color: 'blue', start_date: '05-07-2024', duration: 1 },
        { id: '2-23', parent: 2, text: '工', color: 'blue', start_date: '06-07-2024', duration: 1 },
        { id: '2-24', parent: 2, text: '工', color: 'blue', start_date: '07-07-2024', duration: 1 },
        { id: '2-25', parent: 2, text: '工', color: 'blue', start_date: '08-07-2024', duration: 1 },
        { id: '2-26', parent: 2, text: '工', color: 'blue', start_date: '09-07-2024', duration: 1 },
        { id: '2-27', parent: 2, text: '闲', color: 'green', start_date: '10-07-2024', duration: 1 },
        { id: '2-28', parent: 2, text: '工', color: 'blue', start_date: '11-07-2024', duration: 1 },
        { id: '2-29', parent: 2, text: '工', color: 'blue', start_date: '12-07-2024', duration: 1 },
        { id: '2-30', parent: 2, text: '工', color: 'blue', start_date: '13-07-2024', duration: 1 }, 

        // 第三组
        { id: '3', name: '王五1', render: 'split', text: '' },
        { id: '3-1', parent: 3, text: '工', color: 'blue', start_date: '14-06-2024', duration: 1 },
        { id: '3-2', parent: 3, text: '工', color: 'blue', start_date: '15-06-2024', duration: 1 },
        { id: '3-3', parent: 3, text: '工', color: 'blue', start_date: '16-06-2024', duration: 1 },
        { id: '3-4', parent: 3, text: '工', color: 'blue', start_date: '17-06-2024', duration: 1 },
        { id: '3-5', parent: 3, text: '工', color: 'blue', start_date: '18-06-2024', duration: 1 },
        { id: '3-6', parent: 3, text: '工', color: 'blue', start_date: '19-06-2024', duration: 1 },
        { id: '3-7', parent: 3, text: '工', color: 'blue', start_date: '20-06-2024', duration: 1 },
        { id: '3-8', parent: 3, text: '工', color: 'blue', start_date: '21-06-2024', duration: 1 },
        { id: '3-9', parent: 3, text: '工', color: 'blue', start_date: '22-06-2024', duration: 1 },
        { id: '3-10', parent: 3, text: '工', color: 'blue', start_date: '23-06-2024', duration: 1 },
        { id: '3-11', parent: 3, text: '工', color: 'blue', start_date: '24-06-2024', duration: 1 },
        { id: '3-12', parent: 3, text: '工', color: 'blue', start_date: '25-06-2024', duration: 1 },
        { id: '3-13', parent: 3, text: '工', color: 'blue', start_date: '26-06-2024', duration: 1 },
        { id: '3-14', parent: 3, text: '工', color: 'blue', start_date: '27-06-2024', duration: 1 },
        { id: '3-15', parent: 3, text: '工', color: 'blue', start_date: '28-06-2024', duration: 1 },
        { id: '3-16', parent: 3, text: '工', color: 'blue', start_date: '29-06-2024', duration: 1 },
        { id: '3-17', parent: 3, text: '工', color: 'blue', start_date: '30-06-2024', duration: 1 },
        { id: '3-18', parent: 3, text: '工', color: 'blue', start_date: '01-07-2024', duration: 1 },
        { id: '3-19', parent: 3, text: '工', color: 'blue', start_date: '02-07-2024', duration: 1 },
        { id: '3-20', parent: 3, text: '工', color: 'blue', start_date: '03-07-2024', duration: 1 }, 
        { id: '3-21', parent: 3, text: '工', color: 'blue', start_date: '04-07-2024', duration: 1 }, 
        { id: '3-22', parent: 3, text: '工', color: 'blue', start_date: '05-07-2024', duration: 1 },
        { id: '3-23', parent: 3, text: '工', color: 'blue', start_date: '06-07-2024', duration: 1 },
        { id: '3-24', parent: 3, text: '工', color: 'blue', start_date: '07-07-2024', duration: 1 }, 
        { id: '3-25', parent: 3, text: '工', color: 'blue', start_date: '08-07-2024', duration: 1 },
        { id: '3-26', parent: 3, text: '工', color: 'blue', start_date: '09-07-2024', duration: 1 },
        { id: '3-27', parent: 3, text: '工', color: 'blue', start_date: '10-07-2024', duration: 1 },
        { id: '3-28', parent: 3, text: '工', color: 'blue', start_date: '11-07-2024', duration: 1 },
        { id: '3-29', parent: 3, text: '工', color: 'blue', start_date: '12-07-2024', duration: 1 },
        { id: '3-30', parent: 3, text: '工', color: 'blue', start_date: '13-07-2024', duration: 1 },
    ],
};

// 左侧标题数据
const columns = [
    { name: 'id', label: '序号', resize: true,  max_width: 60, align: "center" },
    { name: 'name', label: '姓名', resize: true, max_width: 60, align: "center" },
];

const GanttView1 = () => {
    // 获取gantrt容器实例
    const ganttRef = useRef<any>();
    // 初始化gantt
    const initGantt = () => {
        gantt.clearAll() // 清空之前的配置
        gantt.i18n.setLocale('cn'); // 设置中文
        gantt.config.readonly = true; // 设置为只读,否则是可以移动甘特图和连线的
        gantt.config.start_date = new Date(2024, 5, 14); // 设置甘特图开始日期  
        gantt.config.end_date = new Date(2024, 6, 14); // 设置甘特图结束日期  
        gantt.init(ganttRef.current); // 初始化甘特图
        gantt.parse(data); // 渲染数据

        gantt.config.columns = columns; // 设置左侧表头数据
        gantt.config.scale_height = 60; // 设置表头高度
        gantt.config.min_column_width = 10; // 设置列最小宽度
        // 设置头部右侧上标题内容背景颜色
        gantt.templates.scale_cell_class = function (scale) {
            return "gantt_grid_head_top";
        };

        gantt.config.scales = [
            { unit: 'month', step: 1, format: function(date) {
                var formattedMonth = gantt.date.date_to_str('%m')(date); // 获取月份的两位数字表示
                formattedMonth = formattedMonth.replace(/^0+/, ''); // 去除月份前面的零
                return formattedMonth + '月'; // 返回格式化后的月份字符串
            }},
            
            { unit: 'day', step: 1, format: function(date) {
                var formattedDay = gantt.date.date_to_str('%d')(date); // 获取天的两位数字表示  
                formattedDay = formattedDay.replace(/^0+/, ''); // 去除天数前面的零  
                return formattedDay; // 返回格式化后的天数字符串  
            }}
        ];

        // 表内容样式设置
        gantt.templates.task_row_class = function (start, end, task) { // 设置表主内容背景颜色
            return "gantt_task_main_content";
        };
        gantt.config.row_height = 40; // 设置内容行高
        gantt.config.bar_height = 40; // 设置进度条高度
        gantt.templates.task_text = function (start, end, task) {
            return `<div style="color: #fff; font-size: 14px;">${task?.text}</div>`;
        };

        // tooltips样式设置
        gantt.plugins({ tooltip: true });
        gantt.config.tooltip_offset_x = 10; // 设置tooltips水平偏移量
        gantt.config.tooltip_offset_y = 30; // 设置tooltips垂直偏移量
        gantt.templates.tooltip_text = function (start: Date, end: Date, task: any): string {
            if (task.text) {
                return (
                    `<div class="gantt-tooltip">
                        <div class="gantt-tooltip-time-space">
                            <div class="time-word">当前时间:</div>
                            <div class="time-value">${start.getMonth() + 1}月${start.getDate()}日</div>
                        </div>
                        <div class="gantt-tooltip-task">
                            <div class="task-word">当前状态:</div>
                            <div class="task-value">${task.text}</div>
                        </div>
                    </div>`
                );
            }
            return "";
        };
    }

    useEffect(() => {
        initGantt();
    }, []);

    return (
        <div className="ganttView2">
            <div className='ganttContainer' ref={ganttRef} style={{ width: '100%' }}></div>
        </div>
    )
};
export default GanttView1;

CSS样式如下:

.ganttView2 {
    width: 100%;
    height: 250px;
    .ganttContainer {
        width: 100vw;
        overflow: hidden;
        height: 100%;
        // 设置左侧头部数据
        .gantt_grid_scale {
            background-color: #dce8ee;
            .gantt_grid_head_cell {
                font-size: 14px;
                font-weight: bold;
                color: #000;
            }
        }
        // 设置右侧头部数据
        .gantt_task_scale {
            background-color: #dce8ee;
            .gantt_grid_head_top {
                font-size: 14px !important;
                font-weight: bold;
                color: #000;
            }
            .gantt_scale_cell {
                font-size: 10px;
                font-weight: bold;
                color: #000;
            }
 
        }
        // 保留左侧标题单元格的竖线  
        .gantt_grid_head_cell,  
        .gantt_grid_data .gantt_cell {  
            border-right: 1px solid #dcdcdc !important; 
        }  
        /* 去除左侧标题和右侧表格内容的激活状态样式 */  
        .gantt_grid_data, .gantt_row.gantt_selected {
            background-color: transparent !important;
        }
     
        // 去除左侧标题内容的悬停效果
        .gantt_row:hover {
            background: none !important; // 去除背景色  
        }
        .gantt_row:active {
            background: none !important; // 去除背景色  
        }
    }
}

// tooltips样式
.gantt_tooltip {
    background-color: #ccc;
    .gantt-tooltip-time-space {
        display: flex;
        align-items: center;
        margin-bottom: 4px;
        align-items: baseline;
        .time-word {
            color: #000;
            font-size: 12px;
            font-weight: bold;
        }
        .time-value {
            color: #000;
        }
    }
    .gantt-tooltip-task {
        display: flex;
        align-items: center;
        .task-word {
            color: #000;
            font-size: 12px;
            font-weight: bold;
        }
        .task-value {
            color: red;
        }
    }
}

实现的界面大家可自行运行,这里不再赘述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1947941.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

temu卖家中心入口登入在哪里,跨境电商temu卖家中心入口登入

在跨境电商的浪潮中&#xff0c;拼多多推出的Temu平台以其独特的商业模式和优惠政策&#xff0c;吸引了众多卖家的目光。对于想要入驻Temu平台的商家而言&#xff0c;找到正确的卖家中心入口并成功登录&#xff0c;是开启跨境电商之旅的第一步。那么&#xff0c;Temu卖家中心入…

QGC二次开发入门教程(一):课程大纲

文章目录 前言一、课程大纲二、修改软件名称三、修改软件图标四、官方QGC中文版BUG修复五、汉化六、修改商标七、添加信号-槽1、添加文件到QGC工程2、添加界面3、QML和C交互4、信号与槽5、测试 八、添加QML和C交互九、MAVLINK的解析与发送十、换地图十一、添加自定义mavlink消息…

3. 手势识别(LeNet、Vgg16、ResNet50)

手势识别 Show me your code1. 模型 model.py2. LeNet 实现手势识别&#xff08;详细&#xff09;2.1 数据打包2.2 搭建模型2.3 训练模型2.4 结果分析2.5 推理过程 3. Vgg16 手势识别4. ResNet50 手势识别 Show me your code 1. 模型 model.py import torch from torch impor…

基于单片机的智能台灯设计

摘 要 &#xff1a; 随着电子产品智能化的发展 &#xff0c; 生活中人们使用的照明工具也逐渐智能化 &#xff0c; 功能也越来越丰富 。 本文介绍了使用单片机进行可调光台灯系统的设计。 通过控制单片机输出高低电平的持续时间 &#xff0c; 从而改变 PWM 的占空比 &#…

el-tree树添加向下移动按钮,前端界面调整顺序

需求&#xff1a;树上添加向下按钮&#xff0c;再不调用接口的情况下&#xff0c;调整树的顺序结构 遇到的问题&#xff1a;第一次点击更新的&#xff0c;数据和视图是调整好的&#xff0c;再次点击页面调整顺序&#xff0c;只有数据被调整了&#xff0c;视图没有发生改变。 &…

【音视频之SDL2】bmp图片与绘制bmp

文章目录 前言BMP是什么SDL2绘制BMP的原理SDL2绘制BMP的流程SDL_LoadBMP作用函数原型参数返回值示例代码 SDL_BlitSurface作用函数原型参数返回值 示例代码效果展示总结 前言 在现代多媒体应用中&#xff0c;图像的处理和显示是非常重要的一部分。无论是在游戏开发还是在视频处…

Qt SQLite数据库编程学习总结

到此为止&#xff0c;就使用Qt进行SQLite数据库的操作&#xff0c;做一次总结 1. Qt中数据库操作的相关概念和类 Qt 数据库编程相关基本概念https://blog.csdn.net/castlooo/article/details/140497177 2.表的只读查询--QSqlQueryModel QSqlQueryModel单表查询的使用总结htt…

Nuxt.js 环境变量配置与使用

title: Nuxt.js 环境变量配置与使用 date: 2024/7/25 updated: 2024/7/25 author: cmdragon excerpt: 摘要&#xff1a;“该文探讨了Nuxt.js框架下环境变量配置的详细过程&#xff0c;涉及.env文件配置、运行时访问、安全性考量、在不同场景下的实践&#xff08;如Vue应用、…

华为OD机试 - 分配土地 (Java 2024年C卷D卷)

华为OD机试&#xff08;C卷D卷&#xff09;2024真题目录(Java & c & python) 题目描述 从前有个村庄&#xff0c;村民们喜欢在各种田地上插上小旗子&#xff0c;旗子上标识了各种不同的数字。 某天集体村民决定将覆盖相同数字的最小矩阵形的土地分配给村里做出巨大贡…

本地电脑连接阿里云

系列文章目录 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、方法1二、使用步骤1.引入库 前言 一、方法1 本地连接远程服务器的时候提示出现身份验证错误的几种解决方法 二、使用步骤 …

巴黎奥运启幕 PLM系统助力中国制造闪耀全球

2024巴黎奥运会将于法国当地时间7月26日在塞纳河畔正式开幕。即将亮相巴黎奥运会赛场的除了中国运动员之外&#xff0c;还有一批批中国制造企业为奥运会设计并制造的体育设备也将惊艳亮相&#xff0c;成为赛场上另一道亮丽的风景线。 在新时代的浪潮中&#xff0c;中国制造业坚…

大道云行,位居中国分布式存储市场挑战者象限!

近日&#xff0c;中国市场咨询机构赛迪顾问发布了《中国分布式存储市场研究报告&#xff08;2024&#xff09;》&#xff08;简称“报告”&#xff09;。报告基于对中国分布式存储市场的深入研究&#xff0c;从发展现状、厂商竞争力、未来趋势入手&#xff0c;结合新环境、新规…

【RHCE】综合真机实验(shell完成)

目录 题目&#xff1a; 需求描述 实操 一、服务端&#xff08;servera&#xff09; 1.ip配置 2.更改主机名 3.创建本地仓库 4.DNS服务 1.下载软件包和防火墙允许 2.配置主配置文件 3.配置区域文件 1.named.exam 2.named.fangxiang 4.重启服务 5.验证结果&#x…

OCDM水下通信仿真代码

一、代码介绍 MATLAB实现&#xff0c;基于OCDM水下基带通信仿真&#xff0c;对比了不同子载波激活的下OCDM水下通信性能&#xff0c;引入多径信道&#xff0c;采用相同信道估计方法,并对比了不同子载波数下的MMSE均衡效果。 信道估计方法参考论文 Robust Channel Estimation …

一款基于Cortex-M0+的单片机音频编解码 - CJC2100

USBCodec芯片可以对数字音频信号进行多种处理&#xff0c;例如增加音量、均衡调节、音效处理等。这些处理可以通过耳机的控制按钮来实现&#xff0c;让用户可以根据自己的喜好来调整音频效果。USBCodec芯片还可以控制噪声和失真的水平&#xff0c;以提供高品质的音频输出。噪声…

单证不一致清关难题 | 国际贸易综合服务平台 | 箱讯科技

什么是单证一致&#xff1f; 单证一致出口方所提供的所有单据要严格符合进口方开证银行所开信用证的要求&#xff0c;或者说出口方制作和提供的所有与本项货物买卖有关的单据&#xff0c;与进口方申请开立的信用证对单据的要求完全吻合&#xff0c;没有矛盾。 添加图片注释&am…

batch norm记录

文章目录 概要整体架构流程训练阶段推理阶段模型中使用的注意事项 概要 面试百度时候被问到了BN 内部详细的训练阶段&#xff0c;推理阶段的计算过程。没回答好&#xff0c;来记录一下 推荐一下b站up: Enzo_Mi。视频做的确实不错 bn 讲解视频 整体架构流程 训练阶段 均值和标…

多模态大模型技术白皮书 2024

不同于语言大模型只对文本进行处理&#xff0c;多模态大模型将文本、语音、图像、视频等多模态数据联合起来进行学习。多模态大模型融合了多种感知途径与表达形态&#xff0c;能够同时处理和理解来自不同感知通道&#xff08;例如视觉、听觉、语言和触觉等&#xff09;的信息&a…

构建生成工具cmake的使用(1)

ps:本文是对cmake的基础讲解&#xff0c;掌握后解决70-80%情况是足以应对的&#xff0c;后续会对cmake有进阶内容。 一 前言 CMake 是一个工具&#xff0c;帮助开发者管理和自动化软件项目的构建过程。它使用一个叫做CMakeLists.txt 的文本文件来描述项目的组织结构、编译选项…

matlab实验:实验六MATLAB 数值计算与符号运算

题目1&#xff1a;&#xff08;线性方程组数值求解&#xff09; 1&#xff0e; 用不同的方法求解下面方程&#xff1a;&#xff08;方程原式参考 P369 实验 10&#xff0c;第 1 题&#xff09; 第 1 种&#xff0c;左除和求逆函数(inv) 第 2 种 &#xff0c; 用 符 号 运 算 的…