jQuery Gantt Chart插件修改

本文介绍如何通过npm下载jQuery Gantt Chart插件,并进行相应的定制和优化,虽然部分细节未详述,但提供了基本操作流程。
摘要由CSDN通过智能技术生成

效果如下:
在这里插入图片描述
npm 下载 插件

在这里插入代码片
/**
 * jQuery Gantt Chart
 *
 * @see http://taitems.github.io/jQuery.Gantt/
 * @license MIT
 */
/*jshint camelcase:true, freeze:true, jquery:true */
(function($, undefined) {
   
    "use strict";

    var UTC_DAY_IN_MS = 24 * 60 * 60 * 1000;

    // custom selector `:findday` used to match on specified day in ms.
    //
    // The selector is passed a date in ms and elements are added to the
    // selection filter if the element date matches, as determined by the
    // id attribute containing a parsable date in ms.
    function findDay(elt, text) {
   
        var cd = new Date(parseInt(text, 10));
        cd.setHours(0, 0, 0, 0);
        var id = $(elt).attr("id") || "";
        var si = id.indexOf("-") + 1;
        var ed = new Date(parseInt(id.substring(si, id.length), 10));
        ed.setHours(0, 0, 0, 0);
        return cd.getTime() === ed.getTime();
    }
    $.expr.pseudos.findday = $.expr.createPseudo ?
        $.expr.createPseudo(function(text) {
   
            return function(elt) {
   
                return findDay(elt, text);
            };
        }) :
        function(elt, i, match) {
   
            return findDay(elt, match[3]);
        };

    // custom selector `:findweek` used to match on specified week in ms.
    function findWeek(elt, text) {
   
        var cd = new Date(parseInt(text, 10));
        var y = cd.getFullYear();
        var w = cd.getWeekOfYear();
        var m = cd.getMonth();
        if (m === 11 && w === 1) {
   
            y++;
        } else if (!m && w > 51) {
   
            y--;
        }
        cd = y + "-" + w;
        var id = $(elt).attr("id") || "";
        var si = id.indexOf("-") + 1;
        var ed = id.substring(si, id.length);
        return cd === ed;
    }
    $.expr.pseudos.findweek = $.expr.createPseudo ?
        $.expr.createPseudo(function(text) {
   
            return function(elt) {
   
                return findWeek(elt, text);
            };
        }) :
        function(elt, i, match) {
   
            return findWeek(elt, match[3]);
        };

    // custom selector `:findmonth` used to match on specified month in ms.
    function findMonth(elt, text) {
   
        var cd = new Date(parseInt(text, 10));
        cd = cd.getFullYear() + "-" + cd.getMonth();
        var id = $(elt).attr("id") || "";
        var si = id.indexOf("-") + 1;
        var ed = id.substring(si, id.length);
        return cd === ed;
    }
    $.expr[':'].findmonth = $.expr.createPseudo ?
        $.expr.createPseudo(function(text) {
   
            return function(elt) {
   
                return findMonth(elt, text);
            };
        }) :
        function(elt, i, match) {
   
            return findMonth(elt, match[3]);
        };

    // Date prototype helpers
    // ======================

    // `getWeekId` returns a string in the form of 'dh-YYYY-WW', where WW is
    // the week # for the year.
    // It is used to add an id to the week divs
    Date.prototype.getWeekId = function() {
   
        var y = this.getFullYear();
        var w = this.getWeekOfYear();
        var m = this.getMonth();
        if (m === 11 && w === 1) {
   
            y++;
        } else if (!m && w > 51) {
   
            y--;
        }
        return 'dh-' + y + "-" + w;
    };

    // `getRepDate` returns the milliseconds since the epoch for a given date
    // depending on the active scale
    Date.prototype.getRepDate = function(scale) {
   
        switch (scale) {
   
            case "hours":
                return this.getTime();
            case "weeks":
                return this.getDayForWeek().getTime();
            case "months":
                return new Date(this.getFullYear(), this.getMonth(), 1).getTime();
            case "days":
                /* falls through */
            default:
                return this.getTime();
        }
    };

    // `getDayOfYear` returns the day number for the year
    Date.prototype.getDayOfYear = function() {
   
        var year = this.getFullYear();
        return (Date.UTC(year, this.getMonth(), this.getDate()) -
            Date.UTC(year, 0, 0)) / UTC_DAY_IN_MS;
    };

    // Use ISO week by default
    //TODO: make these options.
    var firstDay = 1; // ISO week starts with Monday (1); use Sunday (0) for, e.g., North America
    var weekOneDate = 4; // ISO week one always contains 4 Jan; use 1 Jan for, e.g., North America

    // `getWeekOfYear` returns the week number for the year
    //TODO: fix bug when firstDay=6/weekOneDate=1 : https://github.com/moment/moment/issues/2115
    Date.prototype.getWeekOfYear = function() {
   
        var year = this.getFullYear(),
            month = this.getMonth(),
            date = this.getDate(),
            day = this.getDay();
        //var diff = weekOneDate - day + 7 * (day < firstDay ? -1 : 1);
        var diff = weekOneDate - day;
        if (day < firstDay) {
   
            diff -= 7;
        }
        if (diff + 7 < weekOneDate - firstDay) {
   
            diff += 7;
        }
        return Math.ceil(new Date(year, month, date + diff).getDayOfYear() / 7);
    };

    // `getDayForWeek` returns the first day of this Date's week
    Date.prototype.getDayForWeek = function() {
   
        var day = this.getDay();
        var diff = (day < firstDay ? -7 : 0) + firstDay - day;
        return new Date(this.getFullYear(), this.getMonth(), this.getDate() + diff);
    };

    $.fn.gantt = function(options) {
   

        var scales = ["hours", "days", "weeks", "months"];
        //Default settings
        var settings = {
   
            source: [],
            holidays: [],
            // paging
            itemsPerPage: 7,
            // localisation
            dow: ["日", "一", "二", "三", "四", "五", "六"],
            months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
            waitText: "Please wait...",
            // navigation
            navigate: "scroll",
            scrollToToday: false,
            // cookie options
            useCookie: false,
            cookieKey: "jquery.fn.gantt",
            // scale parameters
            scale: "days",
            maxScale: "months",
            minScale: "hours",
            // callbacks
            onItemClick: function(data) {
    return; },
            onAddClick: function(dt, rowId) {
    return; },
            onRender: $.noop
        };

        // read options
        $.extend(settings, options);

        // can't use cookie if don't have `$.cookie`
        settings.useCookie = settings.useCookie && $.isFunction($.cookie);

        // Grid management
        // ===============

        // Core object is responsible for navigation and rendering
        var core = {
   
            // Return the element whose topmost point lies under the given point
            // Normalizes for old browsers (NOTE: doesn't work when element is outside viewport)
            //TODO: https://github.com/taitems/jQuery.Gantt/issues/137
            elementFromPoint: (function() {
    // IIFE
                // version for normal browsers
                if (document.compatMode === "CSS1Compat") {
   
                    return function(x, y) {
   
                        x -= window.pageXOffset;
                        y -= window.pageYOffset;
                        return document.elementFromPoint(x, y);
                    };
                }
                // version for older browsers
                return function(x, y) {
   
                    x -= $(document).scrollLeft();
                    y -= $(document).scrollTop();
                    return document.elementFromPoint(x, y);
                };
            })(),

            // 创建图表
            create: function(element) {
   

                // 使用json对象初始化数据或通过xhr获取数据
                // 请求取决于“settings.source”
                if (typeof settings.source !== "string") {
   
                    element.data = settings.source;
                } else {
   
                    $.getJSON(settings.source, function(jsData) {
   
                        element.data = jsData;
                    });
                }
                element.dataColumns = settings.dataColumns;
                element.dataHeaders = settings.dataHeaders;
                core.init(element);
            },

            // 初始化视图,计算行数、页数、可见的开始时间与结束时间
            init: function(element) {
   
                element.rowsNum = element.data.length;
                element.pageCount = Math.ceil(element.rowsNum / settings.itemsPerPage);
                element.rowsOnLastPage = element.rowsNum - (Math.floor(element.rowsNum / settings.itemsPerPage) * settings.itemsPerPage);

                element.dateStart = tools.getMinDate(element);
                element.dateEnd = tools.getMaxDate(element);

                /* core.render(element); */
                core.waitToggle(element, function() {
    core.render(element); });
            },

            // **渲染grid**
            render: function(element) {
   
                var content = $('<div class="fn-content"/>');
                var $leftPanel = core.leftPanel(element);
                content.append($leftPanel);
                var $rightPanel = core.rightPanel(element, $leftPanel);
                var pLeft, hPos;

                content.append($rightPanel);
                content.append(core.navigation(element));

                var $dataPanel = $rightPanel.find(".dataPanel");

                element.gantt = $('<div class="fn-gantt" />').append(content);

                $(element).empty().append(element.gantt);

                element.scrollNavigation.panelMargin = parseInt($dataPanel.css("left").replace("px", ""), 10);
                element.scrollNavigation.panelMaxPos = ($dataPanel.width() - $rightPanel.width());

                element.scrollNavigation.canScroll = ($dataPanel.width() > $rightPanel.width());

                core.markNow(element);
                core.fillData(element, $dataPanel, $leftPanel);

                // Set a cookie to record current position in the view
                if (settings.useCookie) {
   
                    var sc = $.cookie(settings.cookieKey + "ScrollPos");
                    if (sc) {
   
                        element.hPosition = sc;
                    }
                }

                // Scroll the grid to today's date
                if (settings.scrollToToday) {
   
                    core.navigateTo(element, 'now');
                    core.scrollPanel(element, 0);
                    // or, scroll the grid to the left most date in the panel
                } else {
   
                    if (element.hPosition !== 0) {
   
                        if (element.scaleOldWidth) {
   
                            pLeft = ($dataPanel.width() - $rightPanel.width());
                            hPos = pLeft * element.hPosition / element.scaleOldWidth;
                            element.hPosition = hPos > 0 ? 0 : hPos;
                            element.scaleOldWidth = null;
                        }
                        $dataPanel.css({
    "left": element.hPosition });
                        element.scrollNavigation.panelMargin = element.hPosition;
                    }
                    core.repositionLabel(element);
                }

                $dataPanel.css({
    height: $leftPanel.height() });
                core.waitToggle(element);
                settings.onRender();
            },

            // 创建左侧Panel
            leftPanel: function(element) {
   
                //源码
                /*左侧Panel */
                //var ganttLeftPanel = $('<div class="leftPanel"/>').append($('<div class="row spacer"/>').css("height", tools.getCellSize() * element.headerRows));
                //修改后
                var rowSpace = $('<div class="row spacer"/>');
                var width = "100%";
                if (element.dataHeaders) {
   
                    width = 100 / Object.keys(element.dataHeaders).length + "%";
                }
                $.each(element.dataHeaders, function(name, entryColumn) {
   
                    rowSpace.append($('<div class="dataHead ' + name + '"/>').html(entryColumn).css("width", width).css("border-right", "1px solid #e3e3e3"));
                });
                rowSpace.css("height", tools.getCellSize() * element.headerRows + "px");
                var ganttLeftPanel = $('<div class="leftPanel" style="width: 450px;"/>').append(rowSpace);

                var entries = [];
                var _entries = [];
                $.each(element.data, function(i, entry) {
   
                    // debugger
                    if (i >= element.pageNum * settings.itemsPerPage && i < (element.pageNum * settings.itemsPerPage + settings.itemsPerPage)) {
   
                        //修改后
                        $.each(element.dataColumns, function(ic, entryColumn) {
   
                            entries.push('<div class="row name ' + entryColumn + ' row' + i + '" style="width:' + width + '" id="rowheader' + i + '" data-offset="' + i % settings.itemsPerPage * tools.getCellSize() + '">');
                            entries.push('<span title="' + entry[entryColumn] + '" class="fn-label' + (entry.cssClass ? ' ' + entry.cssClass : '') + '">' + entry[entryColumn] + '</span>');
                            entries.push('</div>');
                        });
                        //源码
                        // var dataId = ('id' in entry) ? '" data-id="' + entry.id : '';
                        // entries.push(
                        //     '<div class="row name row' + i + (entry.desc ? '' : (' fn-wide ' + dataId)) + '" id="rowheader' + i + '" data-offset="' + i % settings.itemsPerPage * tools.getCellSize() + '">' +
                        //     '<span class="fn-label' + (entry.cssClass ? ' ' + entry.cssClass : '') + '">' + (entry.name || '') + '</span>' +
                        //     '</div>'
                        // );

                        // // if (entry.desc) {
   
                        // entries.push(
                        //     '<div class="row desc row' + i + ' " id="RowdId_' + i + dataId + '">' +
                        //     '<span class="fn-label' + (entry.cssClass ? ' ' + entry.cssClass : '') + '">' + entry.desc + '</span>' +
                        //     '</div>'
                        // );
                        // entries.push(
                        //     '<div class="row relationPeople row' + i + ' " id="RowdId_' + i + dataId + '">' +
                        //     '<span class="fn-label' + (entry.cssClass ? ' ' + entry.cssClass : '') + '">' + entry.relationPeople + '</span>' +
                        //     '</div>'
                        // );
                        // // }
                    }
                });
                return ganttLeftPanel.append(entries.join(""));
            },

            // 创建右侧数据Panel
            dataPanel: function(element, width) {
   
                var dataPanel = $('<div class="dataPanel" style="width: ' + width + 'px;"/>');

                // 处理鼠标滚轮事件以滚动数据面板
                // var wheel = 'onwheel' in element ? 'wheel' : document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll';
                // $(element).on(wheel, function(e) { core.wheelScroll(element, e); });

                var mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel";
                if (document.attachEvent) {
   
                    element.attachEvent("on" + mousewheelevt, function(e) {
   
                        core.wheelScroll(element, e);
                    });
                } else if (document.addEventListener) {
   
                    element.addEventListener(mousewheelevt, function(e) {
   
                        core.wheelScroll(element, e);
                    }, false);
                }


                // 处理单击事件并分派到已注册的“onAddClick”函数
                dataPanel.click(function(e) {
   

                    e.stopPropagation();
                    var corrX /* <- never used? */ , corrY;
                    var leftpanel = $(element).find(".fn-gantt .leftPanel");
                    var datapanel = $(element).find(".fn-gantt .dataPanel")
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值