甘特图 dhtmlxGantt.js UA实例

摘要:本文介绍了一个基于AngularJS的排产资源占用甘特图系统,包含前端界面展示和后端控制逻辑。系统通过HTML模板实现甘特图展示区域、查询条件表单和数据绑定,使用JavaScript控制器处理数据查询、甘特图初始化和交互逻辑。主要功能包括:1)查询工厂、作业岛类型的排产资源占用情况;2)甘特图展示资源占用时间分布;3)数据字典加载和表单验证。系统采用只读模式展示甘特图,禁用编辑功能,确保数据安全性和稳定性。 

1.SchedulingResourceOccupationGanTTScreen-list.html

<link href="Scheduling.SchedulingApp/styles/dhtmlxgantt.css" rel="stylesheet">
<style>
    .MainCommandActionButton {
        margin-top: 20px !important;
    }

    /* 启用复制功能 */
    .ui-grid-disable-selection {
        -webkit-touch-callout: default;
        -webkit-user-select: text;
        -khtml-user-select: text;
        -moz-user-select: text;
        -ms-user-select: text;
        user-select: text;
        cursor: auto;
    }
</style>
<div id="itemlist" class="content-area content-area-relative" style="height: calc(93% - 30px) !important">
    <!--查询条件与功能按钮-->
    <div class="col-md-40" style="margin-left: 15px; margin-top: 10px;">
        <div class="side-panel-property-area-body">

            <sit-property-grid sit-id="add_form" sit-layout="Horizontal" sit-type="Fluid" sit-mode="edit"
                sit-columns="5">
                <sit-property sit-widget="sit-select" sit-value="vm.Status.value" sit-validation="{ required: true }"
                    sit-options="vm.Status.options" sit-to-display="'ItemName'" sit-to-keep="'ItemValue'"
                    style="max-width:200px;">查询类型:</sit-property>
                <sit-property sit-widget="sit-select" sit-value="vm.Factory.value" sit-validation="{ required: true }"
                    sit-options="vm.Factory.options" sit-to-display="'ItemName'" sit-to-keep="'ItemValue'"
                    style="max-width:200px;">工厂:</sit-property>

                <sit-property sit-widget="sit-select" sit-value="vm.OperatingIslandType.value"
                    sit-validation="{ required: false }" sit-options="vm.OperatingIslandType.options"
                    sit-to-display="'ItemName'" sit-to-keep="'ItemValue'" style="max-width:200px;">作业岛类型:</sit-property>

                <sit-property sit-widget="sit-datepicker" sit-value="vm.StartDate" sit-validation="{required: true}"
                    sit-options="vm.dateOptions" sit-format="'yyyy-MM-dd'" sit-read-only="false" style="max-width:150px;">开始日期:</sit-property>

                <sit-property sit-widget="sit-datepicker" sit-value="vm.EndDate" sit-validation="{required: true}"
                    sit-options="vm.dateOptions" sit-format="'yyyy-MM-dd'" sit-read-only="false" style="max-width:150px;">结束日期:</sit-property>
                    
                <sit-command-bar sit-type="action">
                    <sit-command sit-icon="fa-search" sit-type="main" sit-name="com.siemens.customcommand.search"
                        sit-tooltip="" ng-show="false" sit-label="">
                    </sit-command> 
                    <sit-command sit-icon="fa-search" sit-type="main" sit-name="com.siemens.customcommand.search" ng-show="vm.validInputs"
                        sit-tooltip="查询" ng-click="vm.searchButtonHandler" sit-label="查询">
                    </sit-command>
                </sit-command-bar>
            </sit-property-grid>
        </div>
    </div>

    <div style="width:100%;margin-top: 5px;">
        <!-- grid列表 -->
        <div id="listClass" style="width:100%; height: 100%; padding:0px 16px 0 16px; margin-top: 3px;">
            <div id="divGantt" class="gantt-container" style="height:90vh;"></div>
        </div>
    </div>



</div>

2.SchedulingResourceOccupationGanTTScreen-list-ctrl.js

(function () {
    'use strict';
    angular.module('Scheduling.SchedulingApp.SchedulingResourceOccupationGanTT').config(ListScreenRouteConfig);

    ListScreenController.$inject = ['Scheduling.SchedulingApp.SchedulingResourceOccupationGanTT.SchedulingResourceOccupationGanTTScreen.service',
        '$state', '$stateParams',
        '$rootScope', '$scope', 'common.services.authentication', 'common.base', 'common.services.logger.service', 'common.widgets.notificationTile.globalService', 'commonService',
        'common.widgets.busyIndicator.service', 'i18nService'];
    function ListScreenController(dataService, $state, $stateParams, $rootScope, $scope, auth, base, loggerService, notificationService, commonService, busyIndicatorService, i18nService) {
        //国际化 
        i18nService.setCurrentLang('zh-cn');
        var self = this;
        var logger, rootstate, messageservice, backendService, signalManager;

        activate();

        // Initialization function
        function activate() {
            logger = loggerService.getModuleLogger('Scheduling.SchedulingApp.SchedulingResourceOccupationGanTT.SchedulingResourceOccupationGanTTScreen');

            init();
            registerEvents();
        }

        function init() {
            logger.logDebug('Initializing controller.......');

            rootstate = 'home.Scheduling_SchedulingApp_SchedulingResourceOccupationGanTT_SchedulingResourceOccupationGanTTScreen';
            messageservice = base.widgets.messageOverlay.service;
            backendService = base.services.runtime.backendService;
            signalManager = base.services.signal.service;

            //Initialize Model Data
            self.selectedItem = null;
            self.isButtonVisible = false;
            self.validInputs = false;
            self.searchButtonHandler = searchButtonHandler;//查询
            //查询类型
            self.Status = {
                value: { 'ItemValue': '作业岛', 'ItemName': '作业岛' },
                options: [

                    { 'ItemValue': '作业岛', 'ItemName': '作业岛' },
                    { 'ItemValue': '班组', 'ItemName': '班组' }
                ]
            };
            //工厂
            self.Factory = {
                value: { 'ItemValue': '', 'ItemName': '--请选择--' },
                options: [
                    { 'ItemValue': '', 'ItemName': '--请选择--' }
                ]
            };
            //作业岛类型
            self.OperatingIslandType = {
                value: { 'ItemValue': '', 'ItemName': '--请选择--' },
                options: [
                    { 'ItemValue': '', 'ItemName': '--请选择--' }
                ]
            };
            //作业岛编号
            self.OperatingIsland = {
                value: { 'ItemValue': '', 'ItemName': '--请选择--' },
                options: [
                    { 'ItemValue': '', 'ItemName': '--请选择--' }
                ]
            };
            self.searchParams = {};
            //获取数据字典
            GetDectionary();
            GanttInit();
        }
        //查询
        function searchButtonHandler(clickedCommand) {
            initGanttData();
        }

        //甘特图初始化
        function GanttInit() {
            //////////////////////////
            //汉化           
            gantt.i18n.setLocale("cn");
            // 完全禁用任务拖动
            // 1. 初始化配置
            gantt.config.date_format = "%Y/%m/%d";
            gantt.config.select_task = false;
            // 禁用所有交互事件(包括双击编辑)
            gantt.config.interaction = {
                click: false,//禁用单击
                dblclick: false,//禁用双击
                drag: false,// 禁用任务拖动
                resize: false//// 禁用调整大小
            };
            // 仅允许查看但禁止修改
            gantt.config.readonly = true;

            // 禁用任务点击选中
            gantt.config.subscales = [
                { unit: "day", step: 1, date: "%D" }
            ];
            // 初始化时禁用任务创建按钮
            gantt.config.show_add_button = false;
            gantt.config.toolbar = []; // 清空工具栏
            gantt.config.show_quick_info = false; // 隐藏快速操作栏
            gantt.config.show_grid_header = false; // 隐藏表头操作栏
            gantt.config.columns = [
                { name: "text", label: "任务名称", width: 200, tree: true },
                { name: "start_date", label: "开始时间", width: 110, align: "center" },
                { name: "end_date", label: "结束时间", width: 110, align: "center" },
                { name: "duration", label: "持续时间", width: 80, align: "center" }
              ];
              
              
            // 2. 加载数据
            gantt.init("divGantt");
            gantt.config.work_time = true;  // 必须启用工作时间模式
            gantt.config.split_tasks = true; // 启用任务分割
            gantt.config.show_unscheduled = true; // 可选:允许显示未安排的任务段
            // 或通过事件拦截(更灵活)
            gantt.attachEvent("onBeforeTaskDrag", function () {
                return false; // 取消拖动操作
            });
        }
        //甘特图数据绑定
        function GantData(serverData) {
            console.log("serverData-------------", JSON.stringify(serverData));
            if (serverData.length==0) {
                console.log("serverData-----1111111111111111111--------");
                //清空数据
                gantt.clearAll(); 
            }
            else {
                console.log("serverData-----22222222222222222--------");
                gantt.parse({
                    data: serverData,
                    // links: [
                    //     { id: 1, source: 2, target: 3, type: "0" } // 0表示"完成-开始"依赖关系
                    // ]
                });
            }

            // 刷新视图使配置生效
            gantt.render();
        }
        //甘特图数据查询
        function initGanttData() {
            self.searchParams.FactoryCode = self.Factory.value.ItemName;
            self.searchParams.OperatingIslandTypeCode = self.OperatingIslandType.value.ItemValue;
            self.searchParams.TypeCode = self.Status.value.ItemValue;
            self.searchParams.StartDate = moment(self.StartDate).format('YYYY-MM-DD HH:mm:ss');
            self.searchParams.EndDate = moment(self.EndDate).format('YYYY-MM-DD HH:mm:ss');
            dataService.getSchedulingGanttList(self.searchParams).then(function (data) {
                if ((data) && (data.succeeded)) {
                    //数据绑定 
                    GantData(data.data.ReturnValue);
                } else {

                }
            }, backendService.backendError);

            // let dd=[
            //     //  { id: 1, text: "PM01", start_date: "2025-05-1", end_date: "2025-05-15", progress: 1 },
            //     {
            //         id: 1,
            //         text: "PM01",
            //         start_date: "2025-05-01", end_date: "2025-05-10"
            //     },
            //     { id: 2, text: "APS000001", start_date: "2025-05-01", end_date: "2025-05-4", parent: 1 },
            //     { id: 3, text: "APS000002", start_date: "2025-05-6 23:59:59", end_date: "2025-05-10", parent: 1 },
            //     { id: 4, text: "PM02", start_date: "2025-05-15", duration: 10, parent: 0 },
            //     { id: 5, text: "PM03", start_date: "2025-05-16", end_date: "2025-05-20", parent: 0 }
            // ];
            // GantData(dd);
        }
        //获取数据字典数据
        function GetDectionary() {
            var dicParamObj = {};
            dicParamObj.ItemCodeList = ['FactoryDic', 'OperatingIslandTypeDic', 'OperatingIslandDic', 'StatusDic'];//可以一次查询多个
            dataService.getDectionary(dicParamObj).then(function (data) {
                if ((data) && (data.succeeded)) {
                    var resData = data.data.DictionaryDataList;
                    //工厂
                    var factoryDicArry = resData.filter(t => t.CategoryCode == 'FactoryDic')
                        .map(function (item) {
                            return { 'ItemValue': item.ItemValue, 'ItemName': item.ItemName }
                        }).sort((a, b) => a.ItemValue.localeCompare(b.ItemValue));
                    self.Factory.options.push(...factoryDicArry);
                    //作业岛类型
                    var operatingIslandTypeDicArry = resData.filter(t => t.CategoryCode == 'OperatingIslandTypeDic')
                        .map(function (item) {
                            return { 'ItemValue': item.ItemValue, 'ItemName': item.ItemName }
                        }).sort((a, b) => a.ItemValue.localeCompare(b.ItemValue));
                    self.OperatingIslandType.options.push(...operatingIslandTypeDicArry);
                    // //作业岛编号
                    // var operatingIslandDicArry = resData.filter(t => t.CategoryCode == 'OperatingIslandDic')
                    //     .map(function (item) {
                    //         return { 'ItemValue': item.ItemValue, 'ItemName': item.ItemName }
                    //     }).sort((a, b) => a.ItemValue.localeCompare(b.ItemValue));
                    // self.OperatingIsland.options.push(...operatingIslandDicArry);

                } else {
                    self.Factory.options = [];
                    self.OperatingIslandType.options = [];
                    self.OperatingIsland.options = [];

                }
            }, backendService.backendError);
        }
        function registerEvents() {
            $scope.$on('sit-property-grid.validity-changed', onPropertyGridValidityChange);
        }
        function onPropertyGridValidityChange(event, params) {
            self.validInputs = params.validity;
        }
    }

    ListScreenRouteConfig.$inject = ['$stateProvider'];
    function ListScreenRouteConfig($stateProvider) {
        var moduleStateName = 'home.Scheduling_SchedulingApp_SchedulingResourceOccupationGanTT';
        var moduleStateUrl = 'Scheduling_SchedulingApp_SchedulingResourceOccupationGanTT';
        var moduleFolder = 'Scheduling.SchedulingApp/modules/SchedulingResourceOccupationGanTT';

        var state = {
            name: moduleStateName + '_SchedulingResourceOccupationGanTTScreen',
            url: '/' + moduleStateUrl + '_SchedulingResourceOccupationGanTTScreen',
            views: {
                'Canvas@': {
                    templateUrl: moduleFolder + '/SchedulingResourceOccupationGanTTScreen-list.html',
                    controller: ListScreenController,
                    controllerAs: 'vm'
                }
            },
            data: {
                title: '排产资源暂用甘特图'
            }
        };
        $stateProvider.state(state);
    }
}());

### dhtmlxGantt.js 中 `duration` 属性的使用 在 dhtmlxGantt.js 库中,`duration` 属性用于表示任务持续时间。此属性通常与特定的任务对象关联,并影响甘特图上的显示效果。 对于编辑器配置,可以设置如下: ```javascript var durationEditor = { type: "number", map_to: "duration", min: 0, max: 100 }; ``` 上述代码片段展示了如何创建一个名为 `durationEditor` 的变量来定义输入控件的行为[^1]。该控件允许用户通过界面调整任务的持续时间,范围限定于 0 到 100 单位之间(具体单位取决于应用上下文)。这种设定有助于确保数据有效性并提供直观的操作体验给最终使用者。 为了更好地理解 `duration` 属性的应用场景及其与其他功能模块之间的交互方式,下面给出一段完整的 JavaScript 实现示例,它不仅涵盖了基本的任务管理还包括了 UI 状态保持机制以及样式适配等内容: #### 创建和初始化甘特图实例 首先,在 HTML 文件内引入必要的资源文件之后,可以通过以下脚本启动一个新的甘特图实例: ```javascript gantt.init("gantt_here"); gantt.config.xml_date = "%Y-%m-%d %H:%i"; // 设置默认视图模式和其他全局参数... ``` 这里假设有一个 ID 为 `"gantt_here"` 的 DOM 元素作为图表渲染的目标区域;同时指定了日期格式化字符串以便后续解析 XML 数据源时能够正确识别时间戳信息。 #### 配置任务字段映射关系 接着要做的就是告诉 gantt 组件哪些自定义属性应该被用来填充内部模型结构。这一步骤涉及到修改 `config.lightbox.sections` 和其他相关选项以适应项目需求: ```javascript gantt.attachEvent("onLightbox", function (id) { var task = gantt.getTask(id); // 动态更新 lightbox 表单内的初始值 }); gantt.config.columns = [ {name:"text", label:"Task name", tree:true, width:200}, {name:"start_date", label:"Start time", align:"center"}, {name:"duration", label:"Duration", align:"center"} ]; ``` 这段代码设置了表格列布局,并明确了每一列表头对应的键名。值得注意的是,“duration” 字段在这里得到了特别处理——其标签名称设为 “Duration”,并且居中对齐显示数值型内容。 #### 处理工具栏事件及保存状态 考虑到用户体验方面的要求,每当点击全展/收起按钮时都应当同步记录当前分支的状态变化情况: ```javascript document.getElementById('expandAll').addEventListener('click', function () { gantt.expand(); saveBranchesState(); }); document.getElementById('collapseAll').addEventListener('click', function () { gantt.collapse(); saveBranchesState(); }); ``` 以上逻辑实现了监听指定元素触发的动作,并调用了相应的 API 方法完成节点操作的同时还执行了一次额外的状态存盘动作[^2]。 #### 调整容器尺寸以支持响应式设计 最后但同样重要的一点是要保证甘特图能够在不同设备屏幕上正常呈现出来。为此需遵循官方文档建议的做法即赋予外部包裹层合适的宽高比例约束条件: ```css html, body{ margin:0px; padding:0px; height:100%; /*强制*/ overflow:hidden; } #gantt_here{ position:relative; width:100%; height:100%; } ``` 这些 CSS 规则确保即使是在移动端浏览器环境下也能获得良好的视觉反馈效果[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bingo_BIG

你的鼓励是我最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值