普加项目管理中间件是用于跨浏览器和跨平台应用程序的功能齐全的 Gantt 图表,可满足项目管理应用程序的所有需求,是最完善的甘特图图表库。

普加甘特图内默认提供了一套通用的百分比汇总计算的方法,但是对于有特殊需求的用户,同样有特殊的接口可以来修改,从而满足用户的百分比计算的需求。

相关代码如下:

//自定义计算百分比模块
var MyPercentComplete = function (project) {
    this.project = project;
}
MyPercentComplete.prototype = {
    syncComplete: function (task) {
        this.syncParentComplete(task);
        this.syncChildrenComplete(task);
    },
    syncParentComplete: function (task) {
        var percentCompleteProperty = "Duration";
        var taskUID = task.UID;
        var parentTask = this.project.getParentTask(taskUID);
        if (parentTask != null && parentTask.UID != this.project.rootTaskUID) {
            var _PercentComplete = parentTask.PercentComplete;
            var cs = this.getChildrenAll(parentTask);
            var allDuration = 0, completeDuration = 0;
            for (var i = 0, l = cs.length; i < l; i++) {
                var c = cs[i];
                var duration = parseInt(c[percentCompleteProperty]);
                if (isNaN(duration)) duration = 0;
                var percentComplete = parseFloat(c["PercentComplete"]);
                if (isNaN(percentComplete)) percentComplete = 0;
                allDuration += duration;
                completeDuration += duration * percentComplete / 100;
            }
            parentTask["PercentComplete"] = parseInt(completeDuration / allDuration * 100);
            if (isNaN(parentTask["PercentComplete"])) parentTask["PercentComplete"] = 0;
            this.syncParentComplete(parentTask);
            if (_PercentComplete != parentTask.PercentComplete) {
                this.project.setTaskModified(parentTask, "PercentComplete");
            }
        }
    },
    syncChildrenComplete: function (task) {
        var percentCompleteProperty = "Duration";
        var children = this.getChildrenAll(task);
        var allDuration = 0, completeDuration = 0;
        for (var i = 0, l = children.length; i < l; i++) {
            var c = children[i];
            var duration = parseInt(c[percentCompleteProperty]);
            allDuration += duration;
        }
        completeDuration = allDuration * parseInt(task["PercentComplete"]) / 100;
        var isCompleteAll = allDuration == completeDuration;
        for (var i = 0, l = children.length; i < l; i++) {
            var c = children[i];
            var _PercentComplete = c.PercentComplete;
            var duration = parseInt(c[percentCompleteProperty]);
            if (isNaN(duration)) duration = 0;
            //if (isNaN(percentComplete)) percentComplete = 0;
            if (completeDuration <= 0) {
                c["PercentComplete"] = 0;
            }
            else {
                var d = completeDuration - duration;
                if (d >= 0) c["PercentComplete"] = 100;
                else {
                    c["PercentComplete"] = parseInt(completeDuration / duration * 100);

                    if (isNaN(c["PercentComplete"])) c["PercentComplete"] = 0;
                }
                completeDuration = d;
            }
            //工期为0的任务,特殊处理
            if (isCompleteAll) {
                c["PercentComplete"] = 100;
            }
            if (_PercentComplete != c.PercentComplete) {
                this.project.setTaskModified(c, "PercentComplete");
            }
        }
        //调节好之后,从子任务向上同步父任务
        for (var i = 0, l = children.length; i < l; i++) {
            var c = children[i];
            this.syncParentComplete(c);
        }
    },
    //百分比应该是纯子任务的工期计算, 摘要任务不参与    
    getChildrenAll: function (task) {
        var children = this.project.getChildTasks(task, true);
        var nodes = [];
        for (var i = 0, l = children.length; i < l; i++) {
            var c = children[i];
            if (c.Summary == 0) {
                nodes.push(c);
            }
        }
        return nodes;
    }
}
var pc = new MyPercentComplete(project);
project.setSchedulePercentComplete(pc);