Pages

搜尋此網誌

2014年5月4日 星期日

extjs: 第三方套件 bryntum 之 gantt scheduling 使用簡介

extjs: 第三方套件 bryntum 之 gantt scheduling 使用簡介

最近因為某些原因有機會玩玩 gantt 圖的拖拉互動 web 介面,剛好又是基於 extjs 的套件,花了一點時間了解一下,在這與大家分享,若有需要使用此套件可以更加快速上手。

此套件的官網: Bryntum: HTML5 Gantt & Scheduling Charts,其相關套件如下圖:

enter image description here

算是完成度蠻高的套件,對於有需要甘特圖拖拉排定順序類是 ms project 的功能要做 web 版使用此套件算是剛剛好。

Bryntum gantt scheduleing

與 extjs 相同,Bryntum 也有其元件相關 API 文件,參考下面連結:

bryntum gantt scheduleing API

使用與查詢方式跟 extjs 官方一樣,若本來就熟悉 extjs 使用上沒有太大的問題。

Online Demo

若要把玩 bryntum 官方提供的 demo,可使用下列連結進行操作:

examples/gantt-scheduler

本機測試

知道大概的操作方法後,為了更加了解內部運作,把該範例的運行環境建置完成,透過最近接觸的 node.js + sails 建置,source code: extjs-bryntum-gantt-demo,相關執行步驟可參考 readme.md

Gnt model

了解一個系統的運作,需要先知道其資料結構,可以參考 bryntum gantt scheduleing API 中關於 Gnt.data.TaskStore 的介紹,連結中有大概的資料表,資料表中欄位的詳細說明可參考:

其中 Gnt.data.TaskStorebryntum gantt scheduleing API 中可以看到該類別是繼承於 Ext.data.TreeStore,所以 TreeStore 有的函式基本上都可在 TaskStore 呼叫,若只針對甘特圖的讀取跟儲存,我們來看下面程式碼:

github 連結: TaskStore.js

Ext.define("MyApp.store.TaskStore", {
    extend      : 'Gnt.data.TaskStore',
    rootVisible : true,
    proxy       : 'memory',

    constructor : function (config) {
        config.calendar = new Gnt.data.calendar.BusinessTime({
            calendarId : "Default",
            name       : "Default"
        });

        this.callParent(arguments);
    },


    //讀取資料來源
    //this.url = data.js 參考 assets/data.js,在這可以替換為從後端 server 取得初始資料
    loadDataSet : function () {
        Ext.Ajax.request({
            url      : this.url,
            method   : 'GET',
            success  : this.populateDataStores,
            callback : function () {
                this.fireEvent('load');
            },
            scope    : this
        });
    },

    // 取得甘特圖操作後的資料並且將資料送交指定網址
    saveDataSet : function () {

        //getModifiedRecords() -> 屬於 Ext.data.TreeStore 的函式,新增或修改的資料可透過此函式取得
        //getRemovedRecords() -> 屬於 Ext.data.AbstractStore 的函式,若要取得刪除的 dependencies 或 task 可用此函式

        var resources = this.resourceStore.getModifiedRecords();
        var assignments = this.assignmentStore.getModifiedRecords();
        var dependencies = this.dependencyStore.getModifiedRecords();
        var tasks = this.getModifiedRecords();

        //將資料一一存為陣列
        function extract(records) {
            var result = [];

            Ext.each(records, function(record) {
                result.push(record.data);
            });

            return result;
        }

        var data = {
            resources    : extract(resources),
            assignments  : extract(assignments),
            dependencies : extract(dependencies),
            tasks        : extract(tasks)
        };


        // 由後端進行資料儲存
        Ext.Ajax.request({
            url      : "/gantt/save",
            method   : 'POST',
            jsonData : data,

            callback : function () {
                this.fireEvent('save');
            },
            scope    : this
        })
    },

    //從後端取得資料後,一一將資料 load 到對應的 store
    populateDataStores : function (response, options) {
        var data = Ext.decode(response.responseText);

        if (data.calendars && data.calendars["default"]) {
            this.calendar.loadData(data.calendars["default"]);
        }

        if (data.dependencies) {
            this.dependencyStore.loadData(data.dependencies);
        }

        if (data.assignments) {
            this.assignmentStore.loadData(data.assignments);
        }

        if (data.resources) {
            this.resourceStore.loadData(data.resources);
        }

        // Now all is in place, continue with tasks
        this.setRootNode(data);
    }
})
;

相關說明都在程式註解中,其中就如一開始有提到的 Gnt.data.TaskStore繼承於 Ext.data.TreeStore,所以我們可以透過下列函式來取得變更後的資料:

屬於 bryntum gantt scheduling 範圍大概就到這,剩下的就是後端的資料處理與回存,希望可以幫到有需要的人囉!

張貼留言