Overview

GanttSheet is a fast, data-bound DataTable view with gantt behavior and a spreadsheet user interface.

Description
app.vue
index.html
styles.css
Copy to CodeMine

Initialization

SpreadJS GanttSheet supports using a DataManager View as a data source.

To use the GanttSheet, add the js file link into the document's head section:

    <head>
       ...
       <script src='.../spreadjs/gc.spread.sheets.all.x.x.x.min.js' type='text/javascript'></script>
       <script src='.../spreadjs/plugins/gc.spread.sheets.tablesheet.x.x.x.min.js' type='text/javascript'></script>
       <script src='.../spreadjs/plugins/gc.spread.sheets.ganttsheet.x.x.x.min.js' type='text/javascript'></script>
    </head>

Then you can use the DataManager with the hierarchy schema:

//init a data manager
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), {sheetCount: 0});
var dataManager = spread.dataManager();
var apiUrl = "ganttsheet_data_api_url";
myTable = dataManager.addTable("myTable", {
    batch: true,
    remote: {
        read: {
            url: apiUrl
        },
        batch: {
            url: apiUrl
        }
    },
    schema: {
        hierarchy: {
            type: "Parent",
            column: "parentId"
        },
        columns: {
            id: { isPrimaryKey: true },
            taskNumber: { dataType: "rowOrder" }
        }
    }
});

You can then define the correct hierarchy schema based on your source data structure.

// the id-parentId structure
schema: {
    hierarchy: {
        type: "Parent",
        column: "parentId"
    },
    columns: {
        id: { isPrimaryKey: true }, // the primary key is required in Id-ParentId type, so that we could build the hierarchy tree nodes
        taskNumber: { dataType: "rowOrder" } // the row order is required in Id-ParentId type, to make sure the you could update the correct data
    }
}

// the level structure
schema: {
    hierarchy: {
        type: "Level",
        column: "level"
    }
}

// the children tree structure
schema: {
    hierarchy: {
        type: "ChildrenPath",
        column: "children"
    }
}

Then initialize a GanttSheet.

var ganttSheet = spread.addSheetTab(0, "GanttSheet", GC.Spread.Sheets.SheetType.ganttSheet);
var view = myTable.addView("ganttView", [
    { value: "taskNumber", caption: "Task Number", width: 100 },
    { value: "mode", caption: "Mode", width: 65 },
    { value: "name", caption: "Task Name", width: 280 },
    { value: "duration", caption: "Duration", width: 90 },
    { value: "start", caption: "Start", width: 120 },
    { value: "finish", caption: "Finish", width: 120 },
    { value: "predecessors", caption: "Predecessors", width: 120 }
]);
view.fetch().then(function() {
    ganttSheet.bindGanttView(view);
});

Batch Mode

The project data records in a GanttSheet are structured data, so batch mode should be used.

Gantt Column

GanttSheets have a property called enableGanttColumn that controls whether to show the gantt column.

By default, this option is true. If you don't want to show it, you can set this property to false when you create GanttSheet or call ganttSheet.bindGanttView(view, { enableGanttColumn: false }).

Initialization SpreadJS GanttSheet supports using a DataManager View as a data source. To use the GanttSheet, add the js file link into the document's head section: Then you can use the DataManager with the hierarchy schema: You can then define the correct hierarchy schema based on your source data structure. Then initialize a GanttSheet. Batch Mode The project data records in a GanttSheet are structured data, so batch mode should be used. Gantt Column GanttSheets have a property called enableGanttColumn that controls whether to show the gantt column. By default, this option is true. If you don't want to show it, you can set this property to false when you create GanttSheet or call ganttSheet.bindGanttView(view, { enableGanttColumn: false }).
/*REPLACE_MARKER*/ /*DO NOT DELETE THESE COMMENTS*/ <template> <div class="sample-tutorial"> <gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread" > </gc-spread-sheets> </div> </template> <script> import Vue from "vue"; import "@mescius/spread-sheets-vue"; import GC from "@mescius/spread-sheets"; import "@mescius/spread-sheets-tablesheet"; import "@mescius/spread-sheets-ganttsheet"; import "./styles.css"; let App = Vue.extend({ name: "app", data: function() { return { spread: null } }, methods: { initSpread: function (spread) { this.spread = spread; spread.suspendPaint(); spread.clearSheets(); this.initGanttSheetWithIdParentIdData(spread); this.initGanttSheetWithLevelData(spread); this.initGanttSheetWithChildrenData(spread); spread.resumePaint(); }, initGanttSheetWithIdParentIdData(spread) { var tableName = "Gantt_Id"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var dataManager = spread.dataManager(); var myTable1 = dataManager.addTable("myTable1", { batch: true, remote: { read: { url: apiUrl } }, schema: { hierarchy: { type: "Parent", column: "parentId" }, columns: { id: { isPrimaryKey: true }, taskNumber: { dataType: "rowOrder" } } } }); var ganttSheet = spread.addSheetTab(0, "GanttSheet1", GC.Spread.Sheets.SheetType.ganttSheet); var view = myTable1.addView("myView1", [ { value: "taskNumber", caption: "NO", width: 60 }, { value: '=CONCAT("(L",LEVEL(),"-",LEVELROWNUMBER(),")")', caption: "L" }, { value: "name", caption: "Task Name", width: 200 }, { value: "duration", caption: "Duration", width: 90 }, { value: "predecessors", caption: "Predecessors", width: 60 }, { value: "cost", caption: "Cost", style: { formatter: "$0" } } ]); view.fetch().then(function() { ganttSheet.bindGanttView(view); }); }, initGanttSheetWithLevelData(spread) { var tableName = "Gantt_Level"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var dataManager = spread.dataManager(); var myTable1 = dataManager.addTable("myTable1", { batch: true, remote: { read: { url: apiUrl } }, schema: { hierarchy: { type: "Level", column: "level" } } }); var ganttSheet = spread.addSheetTab(1, "GanttSheet2", GC.Spread.Sheets.SheetType.ganttSheet); var view = myTable1.addView("myView1", [ { value: "taskNumber", caption: "NO.", width: 60 }, { value: "name", caption: "Task Name", width: 200 }, { value: "duration", caption: "Duration", width: 90 }, { value: "predecessors", caption: "Predecessors", width: 120 } ]); view.fetch().then(function() { ganttSheet.bindGanttView(view); }); }, initGanttSheetWithChildrenData(spread) { var tableName = "Gantt_Children"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var dataManager = spread.dataManager(); var myTable1 = dataManager.addTable("myTable1", { batch: true, remote: { read: { url: apiUrl } }, schema: { hierarchy: { type: "ChildrenPath", column: "children" } } }); var ganttSheet = spread.addSheetTab(2, "GanttSheet3", GC.Spread.Sheets.SheetType.ganttSheet); var view = myTable1.addView("myView1", [ { value: "taskNumber", caption: "NO.", width: 60 }, { value: "name", caption: "Task Name", width: 200 }, { value: "duration", caption: "Duration", width: 90 }, { value: "predecessors", caption: "Predecessors", width: 120 } ]); view.fetch().then(function() { ganttSheet.bindGanttView(view); }); } } }); function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/demos\//)[0] + 'server/api'; } new Vue({ render: (h) => h(App), }).$mount("#app"); </script>
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/vue/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- SystemJS --> <script src="$DEMOROOT$/en/vue/node_modules/systemjs/dist/system.src.js"></script> <script src="$DEMOROOT$/spread/source/data/employees.js" type="text/javascript"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app.vue'); System.import('$DEMOROOT$/en/lib/vue/license.js'); </script> </head> <body> <div id="app"></div> </body> </html>
.sample-tutorial { width: 100%; height: 100%; } body, html { padding: 0; margin: 0; width: 100%; height: 100%; position: relative; overflow: hidden; } .sample-spreadsheets { width: 100%; height: 100%; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' }, '*.vue': { loader: 'vue-loader' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js', '@mescius/spread-sheets-ganttsheet': 'npm:@mescius/spread-sheets-ganttsheet/index.js', '@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'css': 'npm:systemjs-plugin-css/css.js', 'vue': 'npm:vue/dist/vue.min.js', 'vue-loader': 'npm:systemjs-vue-browser/index.js', 'tiny-emitter': 'npm:tiny-emitter/index.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' } } }); })(this);