「實戰應用」如何用DHTMLX構建自定義JavaScript甘特圖(二)

DHTMLX Gantt是用於跨瀏覽器和跨平臺應用程序的功能齊全的Gantt圖表。可滿足項目管理應用程序的所有需求,是最完善的甘特圖圖表庫。

當您聲稱您的產品具有高級定製功能時,客戶一定會對產品進行嚴格測試,這個規則當然適用於DHTMLX Gantt,官方技術團隊收到了很多關於如何在JavaScript甘特圖組件中實現某些外觀定製的請求,結合實際的案例,我們將在本文中爲您展示如何在實踐中實現這些定製。在上文中(點擊這裏回顧>>),我們主要介紹了JavaScript甘特圖用例以及如何可是構建一個JS甘特圖,本文將繼續介紹如何構建JS甘特圖。

爲任務分配資源

下一個特性是將資源(在我們的例子中是員工)分配給任務的能力,DHTMLX Gantt以廣泛的資源管理能力而聞名,包括一個單獨的資源面板。

但是如果您需要對單個元素進行更簡單的配置,則可以使用簡化形式的資源。

在我們的演示中,有一個數組其中指定了員工的姓名和照片,這意味着這些數據可以從服務器加載。

const resourceData = [
{ "key": "1", "label": "John" },
{ "key": "2", "label": "Mike" },
{ "key": "3", "label": "Anna" },
{ "key": "4", "label": "Bill" },
{ "key": "5", "label": "Floe" },
]

DHTMLX Gantt有一個lightbox部分,使您能夠爲一個任務分配多個資源並指定資源值(小時,天,材料等)。爲了使其正常工作,您需要在options參數中指定一個帶有資源的數組。

{ name: "resources", type: "resources", map_to: "owners", options: resourceData, default_value: 8 },

如果使用簡單的甘特配置(gantt.config.resources) 並且使用load()或parse()方法從服務器加載資源,Gantt將自動向lightbox部分添加必要的參數。

當使用自定義配置時,數組必須包含帶有key和label參數的對象。

在我們的演示中,還顯示了網格部分中分配給任務的資源(員工照片)。爲此需要使用列配置的模板函數,其中將返回getOwnerPics函數的值。

name: "owners", label: "Owners", resize: true, width: 75, template: function (task) {
return getOwnerPics(task);
}

在這個函數中,有必要使用owner任務屬性,其中指定了分配的資源。如果存在分配,則應該將資源ID添加到單獨的所有者數組中。

下一步是用資源數據遍歷數組,如果資源ID在所有者數組中,則獲取帶有照片的屬性並將其添加到images變量中,之後返回這個包含所有員工照片的變量。

function getOwnerPics(task) {
let images = "";

const owners = [];
(task.owners || []).forEach(function (el) {
owners.push(el.resource_id);
})

resourceData.forEach(function (resource) {
if (owners.indexOf(resource.key) > -1) {
images += " " + resource.img || "";
}
})

return images;
}

任務欄中的任務名稱和資源

如果您看了Gantt演示,可以看到一些任務欄中顯示了任務名稱和資源圖像。如果它們不適合,這些元素將顯示在任務欄的右側。

要確定任務名稱和員工圖像是否可以放置在任務欄中,需要應用detectOverflow函數。在這個函數中,首先使用getTaskPosition()方法來獲取任務欄的座標。因爲您只需要任務欄的寬度,所以從getTaskPosition()方法返回的對象中獲取寬度參數。

const taskWidth = gantt.getTaskPosition(task, task.start_date, task.end_date).width;

然後需要創建canvas元素,使用getComputedStyle()方法查找通常在任務欄中顯示的文本字體樣式和字體大小。之後在context元素中指定這些參數,並使用measureText()方法來確定文本寬度。

const canvas = document.createElement('canvas');
const context = canvas.getContext("2d");

const bar = document.querySelector(".gantt_task_content")
if (bar) {
const fontFamily = getComputedStyle(bar)['font-family'];
const fontSize = getComputedStyle(bar)['font-size'];
context.font = fontSize + ' ' + fontFamily;
}
const textWidth = context.measureText(task.text).width;

現在是時候將照片添加到任務欄了,您需要指定這些照片的寬度。在我們的演示中,圖像的寬度被調整爲任務欄的高度,因此您可以使用gantt.config.row_height配置的值。但如果元素的寬度不同,則需要設置一個新值,寬度值必須乘以分配給給定任務的資源數量。

const ownersWidth = (task.owners || []).length * gantt.config.row_height;

現在有必要對文本和圖像的寬度值進行總結,如果結果值大於任務欄的寬度,則返回true,這意味着內容(文本+照片)不會包含在任務欄中。

if (textWidth + ownersWidth > taskWidth) {
return true;
}

如果detectOverflow返回false,則task_text模板包含以下條件。如果任務類型是項目,則只需返回任務文本。如果它是一個常規任務,則返回一個HTML元素,其中包含任務文本和可以從getOwnerPics函數獲得的員工照片。

gantt.templates.task_text = function (start, end, task) {
if (detectOverflow(task)) {
return ""
}
else {
if (task.type == gantt.config.types.project) {
return task.text;
}
else {
return `<span style="vertical-align: top" >${task.text}</span>${getOwnerPics(task)}`;
}
}
};

在rightside_text模板中,對“task”類型的任務使用detectOverflow函數。如果此函數返回true,則應該返回一個HTML元素,其中包含來自getOwnerPics函數的任務文本和員工圖像。

在DHTMLX Gantt中可以只使用一個模板,您不能多次指定不同的模板並期望它們正常工作,所以必須在一個模板中添加所有的代碼:

gantt.templates.rightside_text = function (start, end, task) {
if (task.type == gantt.config.types.project) {
return `<div class='project-right' style="${getTriangleStyles(task, "right")}"></div>`
}


if (detectOverflow(task)) {
return `<span style="vertical-align: top" >${task.text}</span>${getOwnerPics(task)}`;
}
return "";
};

由於篇幅有限,下期繼續講解,請持續關注查看最新產品資訊哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章